laravel 采摘多列?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42947515/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 17:41:29  来源:igfitidea点击:

Pluck with multiple columns?

laravellaravel-5laravel-5.2

提问by None

When i use pluck with multiple columns i get this:

当我对多列使用 pluck 时,我得到了这个:

{"Kreis 1 \/ Altstadt":"City","Kreis 2":"Enge","Kreis 3":"Sihifeld","Kreis 4":"Hard","Kreis 5 \/ Industriequartier":"Escher Wyss","Kreis 6":"Oberstrass","Kreis 7":"Witikon","Kreis 8 \/ Reisbach":"Weinegg","Kreis 9":"Altstetten","Kreis 10":"Wipkingen","Kreis 11":"Seebach","Kreis 12 \/ Schwamendingen":"Hirzenbach"

But i need this?

但我需要这个?

["Rathaus","Hochschulen","Lindenhof","City","Wollishofen","Leimbach","Enge","Alt-Wiedikon","Friesenberg","Sihifeld","Werd","Langstrasse","Hard","Gewerbechule","Escher Wyss","Unterstrass","Oberstrass","Fluntern","Hottingen","Hirslanden","Witikon","Seefeld","M\u00fchlebach","Weinegg","Albisrieden","Altstetten","H\u00f6ngg","Wipkingen","Affoltern","Oerlikon","Seebach","Saatlen","Schwamendingen-Mitte","Hirzenbach"]

Any suggestion how can i do that? This is my method:

任何建议我该怎么做?这是我的方法:

    public function autocomplete_districts(Request $request)
   {
      $district = $request->input('query');
      // $ass = /DB::table('districts')->select(array('district', 'region'))->get();
      // dd($ass);
      $data = Districts::whereRaw('LOWER(district) like ?', [strtolower('%'.$district . '%')])->orWhereRaw('LOWER(region) like ?', [strtolower('%'.$district . '%')])->pluck('region','district');

      return response()->json($data);
   }

回答by Learner

You should use select()with get()and then later on modify the object as you need.

您应该使用select()withget()然后稍后根据需要修改对象。

So instead of: ->pluck('region','district');use: ->select('region','district')->get();

所以而不是:->pluck('region','district');使用:->select('region','district')->get();

pluck()is advised when you need value of one column only.

pluck()当您只需要一列的值时,建议使用。

And as far as possible, you should have your models singular form not plural (Districts) - to follow Laravel nomenclature.

并且尽可能地,你应该让你的模型单数形式而不是复数形式(区) - 遵循 Laravel 命名法。

回答by Saravanan Sampathkumar

Cos that is how pluck works. Instead try this.

因为这就是 pluck 的工作原理。而是试试这个。

$data = Districts::whereRaw('LOWER(district) like ?', [strtolower('%'.$district . '%')])->orWhereRaw('LOWER(region) like ?', [strtolower('%'.$district . '%')])->select('region', 'district')->get();

$data = collect($data->toArray())->flatten()->all();

回答by JustCarty

This is an issue I constantly have faced and has led me to create the following solution that can be used on models or arrays.
There is also support for dot syntax that will create a multidimensional array as required.

这是我经常遇到的一个问题,并促使我创建了以下可用于模型或阵列的解决方案。
还支持点语法,可根据需要创建多维数组。

Register this macro within the AppServiceProvider(or any provider of your choice):

AppServiceProvider(或您选择的任何提供程序)中注册此宏:

/**
 * Similar to pluck, with the exception that it can 'pluck' more than one column.
 * This method can be used on either Eloquent models or arrays.
 * @param string|array $cols Set the columns to be selected.
 * @return Collection A new collection consisting of only the specified columns.
 */
    Collection::macro('pick', function ($cols = ['*']) {
    $cols = is_array($cols) ? $cols : func_get_args();
    $obj = clone $this;

    // Just return the entire collection if the asterisk is found.
    if (in_array('*', $cols)) {
        return $this;
    }

    return $obj->transform(function ($value) use ($cols) {
        $ret = [];
        foreach ($cols as $col) {
            // This will enable us to treat the column as a if it is a
            // database query in order to rename our column.
            $name = $col;
            if (preg_match('/(.*) as (.*)/i', $col, $matches)) {
                $col = $matches[1];
                $name = $matches[2];
            }

            // If we use the asterisk then it will assign that as a key,
            // but that is almost certainly **not** what the user
            // intends to do.
            $name = str_replace('.*.', '.', $name);

            // We do it this way so that we can utilise the dot notation
            // to set and get the data.
            array_set($ret, $name, data_get($value, $col));
        }

        return $ret;
    });
});

This can then be used in the following way:

然后可以通过以下方式使用它:

$a = collect([
    ['first' => 1, 'second' => 2, 'third' => 3],
    ['first' => 1, 'second' => 2, 'third' => 3]
]);

$b = $a->pick('first', 'third'); // returns [['first' => 1, 'third' => 3], ['first' => 1, 'third' => 3]]

Or additionally, on any models you may have:

或者另外,在您可能拥有的任何型号上:

$users = User::all();
$new = $users->pick('name', 'username', 'email');
// Might return something like:
// [
//     ['name' => 'John Doe', 'username' => 'john', 'email' => '[email protected]'],
//     ['name' => 'Jane Doe', 'username' => 'jane', 'email' => '[email protected]'],
//     ['name' => 'Joe Bloggs', 'username' => 'joe', 'email' => '[email protected]'],
// ]

It is also possible to reference any relationship too using the dot notation, as well as using the as [other name]syntax:

也可以使用点表示法以及使用as [other name]语法来引用任何关系:

$users = User::all();
$new = $users->pick('name as fullname', 'email', 'posts.comments');
// Might return something like:
// [
//     ['fullname' => 'John Doe', 'email' => '[email protected]', 'posts' => [...]],
//     ['fullname' => 'Jane Doe', 'email' => '[email protected]', 'posts' => [...]],
//     ['fullname' => 'Joe Bloggs', 'email' => '[email protected]', 'posts' => [...]],
// ]

回答by Manojkiran.A

I have created the model scope

我已经创建了模型范围

More about scopes:

有关范围的更多信息:

Code:

代码:

/**
 * Scope a query to Pluck The Multiple Columns
 *
 * This is Used to Pluck the multiple Columns in the table based
 * on the existing query builder instance
 *
 * @author Manojkiran.A <[email protected]>
 * @version 0.0.2
 * @param  \Illuminate\Database\Eloquent\Builder $query
 * @param string $keyColumn the columns Which is used to set the key of array
 * @param array $extraFields the list of columns that need to plucked in the table
 * @return \Illuminate\Support\Collection
 * @throws Illuminate\Database\QueryException
 **/
public function scopePluckMultiple( $query, string $keyColumn, array $extraFields):\Illuminate\Support\Collection
{
    //pluck all the id based on the query builder instance class
    $keyColumnPluck = $query->pluck( $keyColumn)->toArray();
    //anonymous callback method to iterate over the each fileds of table
    $callBcakMethod = function ($eachValue) use ($query)
    {
        $eachQuery[$eachValue] = $query->pluck( $eachValue)->toArray();
        return $eachQuery;
    };
    //now we are collapsing the array single time to get the propered array 
    $extraFields = \Illuminate\Support\Arr::collapse( array_map($callBcakMethod, $extraFields));

    // //iterating Through All Other Fields and Plucking it each Time
    // foreach ((array)$extraFields as  $eachField) {
    //         $extraFields[$eachField] =   $query->pluck($eachField)->toArray();
    //     }

    //now we are done with plucking the Required Columns
    //we need to map all the values to each key

    //get all the keys of extra fields and sets as array key or index
    $arrayKeys = array_keys($extraFields);
    //get all the extra fields array and mapping it to each key
    $arrayValues = array_map(
        function ($value) use ($arrayKeys) {
            return array_combine($arrayKeys, $value);
        },
        call_user_func_array('array_map', array_merge(
            array(function () {
                return func_get_args();
            }),
            $extraFields
        ))
    );
    //now we are done with the array now Convert it to Collection
    return collect( array_combine( $keyColumnPluck, $arrayValues));
}

So now the testing part

所以现在是测试部分

BASIC EXAMPLE

基本示例

$basicPluck  = Model::pluckMultiple('primaryKeyFiles',['fieldOne', 'FieldTwo']);

ADVANCED EXAMPLE

高级示例

$advancedPlcuk  = Model::whereBetween('column',[10,43])
                            ->orWhere('columnName','LIKE', '%whildCard%')
                            ->Where( 'columnName', 'NOT LIKE', '%whildCard%')
                            ->pluckMultiple('primaryKeyFiles',['fieldOne', 'FieldTwo']);

But it returns the \Illuminate\Support\Collection, so if you need to convert to array

但它返回\Illuminate\Support\Collection,因此如果您需要转换为数组

$toArrayColl = $advancedPluck->toArray();

if you need to convert to json

如果你需要转换成json

$toJsonColl = $advancedPluck->toJson();

回答by Adnan Ahmad

Laravel:To pluck multi-columns in the separate arrays use the following code.

Laravel:要在单独的数组中提取多列,请使用以下代码。

$Ads=Ads::where('status',1);
$Ads=$Ads->where('created_at','>',Carbon::now()->subDays(30));
$activeAdsIds=$Ads->pluck('id'); // array of ads ids
$UserId=$Ads->pluck('user_id'); // array of users ids

回答by David Notrac

My solution in LARAVEL 5.6:

我在 LARAVEL 5.6 中的解决方案:

Hi, I've just had the same problem, where I needed 2 columns combined in 1 select list. My DB has 2 columns for Users: first_name and last_name. I need a select box, with the users full name visible and the id as value. This is how I fixed it, using the pluck() method:

嗨,我刚刚遇到了同样的问题,我需要将 2 列合并到 1 个选择列表中。我的数据库有 2 列用户:first_name 和 last_name。我需要一个选择框,用户全名可见,id 作为值。这是我修复它的方法,使用 pluck() 方法:

In the User model I created a full name accessor function:

在 User 模型中,我创建了一个全名访问器函数:

public function getNameAttribute() {
    return ucwords($this->last_name . ' ' . $this->first_name);
}

After that, to fill the select list with the full name & corresponding database id as value, I used this code in my controller that returns the view (without showing users that are archived, but you can change the begin of the query if you like, most important are get() and pluck() functions:

之后,为了使用全名和相应的数据库 ID 作为值填充选择列表,我在我的控制器中使用了此代码来返回视图(不显示已存档的用户,但您可以根据需要更改查询的开头) ,最重要的是 get() 和 pluck() 函数:

$users = User::whereNull('archived_at')
    ->orderBy('last_name')
    ->get(['id','first_name','last_name'])
    ->pluck('name','id');
return view('your.view', compact('users'));

Now you can use the $users in your select list!

现在您可以在选择列表中使用 $users 了!

So first, you GET all the values from DB that you will need, after that you can use any accessor attribute defined for use in your PLUCK method,

因此,首先,您从数据库中获取您需要的所有值,然后您可以使用定义用于 PLUCK 方法的任何访问器属性,

as long as all columns needed for the accessor are in the GET ;-)

只要访问器所需的所有列都在 GET 中;-)