采用多列?

时间:2017-03-22 09:31:45

标签: laravel laravel-5 laravel-5.2

当我使用多列的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"

但我需要这个吗?

["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"]

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

    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);
   }

8 个答案:

答案 0 :(得分:17)

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

所以代替:->pluck('region','district'); 使用:->select('region','district')->get();

当您只需要一列的值时,建议

pluck()

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

答案 1 :(得分:6)

这就是采摘的方式。而是试试这个。

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

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

答案 2 :(得分:2)

这是我一直面临的问题,导致我创建了可以在模型或数组上使用的以下解决方案。
还支持点语法,该语法将根据需要创建多维数组。

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;
    });
});

然后可以按以下方式使用它:

$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]]

或者,在任何型号上,您都可以拥有:

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

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

我在LARAVEL 5.6中的解决方案:

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

在用户模型中,我创建了一个全名访问器功能:

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

之后,要使用全名和对应的数据库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'));

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

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

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

答案 5 :(得分:0)

对不起,我迟到了几天之前也遇到了同样的情况

我已经创建了模型作用域

有关范围的更多信息

https://laravel.com/docs/5.8/eloquent#query-scopes

https://medium.com/@janaksan_/using-scope-with-laravel-7c80dd6a2c3d

/**
 * 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 <manojkiran10031998@gmail.com>
 * @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 $extraFileds 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 $extraFileds):\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, $extraFileds));

    // //iterating Through All Other Fileds and Plucking it each Time
    // foreach ((array)$extraFileds as  $eachFiled) {
    //         $extraFields[$eachFiled] =   $query->pluck($eachFiled)->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 fileds and sets as array key or index
    $arrayKeys = array_keys($extraFields);
    //get all the extra fileds array and mapping it to eack 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));
}

现在是测试部分

基本示例

$basicPluck  = Model::pluckMultiple('primaryKeyFiles',['filedOne', 'FiledTwo']);

高级示例

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

但是它返回 \ Illuminate \ Support \ Collection ,所以

如果您需要转换为数组

$toArrayColl = $advancedPlcuk->toArray();

如果您需要转换为json

$toJsonColl = $advancedPlcuk->toJson();

答案 6 :(得分:0)

要回答“如何使用pluck(类似)返回多列”这一特定问题,我们必须记住Pluck是Collection成员函数。因此,如果我们坚持提出的问题,我们应该坚持基于集合的答案(您可能会发现开发基于模型的解决方案更有益,但这无助于解决所提出的问题)。

Collection类提供了“ map”成员函数,可以解决所提出的问题:

$data = Districts::whereRaw('LOWER(district) like ?', [strtolower('%'.$district . '%')])->orWhereRaw('LOWER(region) like ?', [strtolower('%'.$district . '%')])
->map(function ($item, $key, $columns=['region','district']) {
        $itemArray = [];
        foreach($columns as $column){
            $itemArray[$column] = $item->$column;
        }
       return ($itemArray);
     });
dd($data);

这应该给您一个集合,其中每个元素是一个由“ region”和“ district”索引的2元素数组。

答案 7 :(得分:0)

到目前为止,Laravel 没有提供这样的宏来选择特定的列,但无论如何 Laravel 是开箱即用的,让我们几乎可以自定义所有内容。

在 Laravel 8.x 中测试

在 AppServiceProvider.php 中

use Illuminate\Support\Collection;

// Put this inside boot() function
Collection::macro('pick', function (... $columns) {
    return $this->map(function ($item, $key) use ($columns) {
        $data = [];
        foreach ($columns as $column) {
            $data[$column] = $item[$column] ?? null;
        }

        return $data;
    });
});

用法

$users = App\Models\User::all();
$users->pick('id','name');
// Returns: [['id' => 1, 'name' => 'user_one'],['id' => 2, 'name' => 'user_two']]

重要说明:

  • 不要将这个宏用于一个非常大的集合(你最好在 Eloquent 上做 选择或 MySQL 查询选择)