雄辩的集合方法,如only或except返回一个空集合

时间:2017-02-01 04:27:40

标签: laravel collections laravel-5.3

docs开始,我使用->only()方法

测试了以下示例
$collection = collect(['product_id' => 1, 'name' => 'Desk', 'price' => 100, 'discount' => false]);

$filtered = $collection->only(['product_id', 'name']);

$filtered->all();

// ['product_id' => 1, 'name' => 'Desk']

它确实有效。

然而,当我将该方法应用于我从数据库(模型)获取的集合时,

$myCollection = MyModel::orderBy('id','desc')->paginate(5);
$filtered=$myCollection->only(['id']);
        dd(filtered);

返回的集合是空的!

Collection {#199 ▼
  #items: []
}

如果我从数据库中获取了集合dd($myCollection);,它确实充满了追加,属性等等。数据在表刀片视图中正确显示。

但是,如果我应用->only()->except()$myCollection方法......返回的集合为空。

例如,这是集合的一部分,我只想显示id属性,或者更多但不是全部:

LengthAwarePaginator {#218 ▼
  #total: 3041
  #lastPage: 609
  #items: Collection {#219 ▼
    #items: array:5 [▼
      0 => MyModel {#220 ▼
        #dates: array:1 [▶]
        #appends: array:5 [▶]
        #connection: null
        #table: null
        #primaryKey: "id"
        #keyType: "int"
        #perPage: 15
        +incrementing: true
        +timestamps: true
        #attributes: array:12 [▼
          "id" => 3041
          "date" => "2017-01-25"
          "value1" => "12"
          "value2" => "20"
          "value3" => "22"
          "value4" => "25"
          "value5" => "46"
          "value6" => "48"
          "value7" => "50"
          "value8" => "$60,000,000.00"
          "created_at" => null
          "updated_at" => null
        ]

但是当我应用->only(['id'])时,该集合将返回空白。

我在没有分页的情况下对其进行了测试,空集合的问题仍然相同,所以我不认为它与LengthAwarePaginator有关。

解决方法 不幸的是,我正在努力实现这一目标:

    $filtered = collect(['id'=>$myCollection->pluck(['id']),'Value1'=>$myCollection->pluck('value1')]);
dd($filtered);

现在我得到了所需的集合,例如我只想要数据库中的两个属性或列:

Collection {#212 ▼
  #items: array:2 [▼
    "id" => Collection {#201 ▶}
    "value1" => Collection {#211 ▶}
  ]
}

为什么会这样?我错过了什么?我该如何解决?

3 个答案:

答案 0 :(得分:7)

请注意SELECT COUNT(*) FROM [myDb].[dbo].[Properties] WHERE Bathtub is null SELECT COUNT(*) FROM [myDb].[dbo].[Properties] WHERE Bathroom is null SELECT COUNT(*) FROM [myDb].[dbo].[Properties] WHERE Toilet is null 将返回带有指定键的项目,该项目应用于具有键或关联数组的数组。作为给出的示例,它是带有键的数组

only()

但是,如果您测试将['product_id' => 1, 'name' => 'Desk', 'price' => 100, 'discount' => false] 与来自eloquent结果的集合一起使用,该结果包含一组集合/对象(没有键)。

only()

如果集合包含密钥,它将起作用。

[ object, object, object ]

因此,在您的情况下,只过滤指定键的值,我建议使用[ 'product_id' => object, 'name' => object ] pluck()

答案 1 :(得分:0)

很可能你会想要使用map而不是像OP建议那样采摘。

<强> TL:DR 使用方法:

$mapped = $myCollection->map(
    function ($item, $key) {
      $item = $item->first(); //as item is a collection of models
      $new = [];
      $new['id']                 = $item->id;
      $new['birthdate']          = $item->birthdate;
      return $new;
    }
);

长版:

注意:groupBy返回集合的集合

$mm = MyModel::get();

//$mm is a collection of Models

所以你有一个

的集合

$mm基本上是

[
0 => MyNamespace\MyModel,
1 => MyNamespace\MyModel,
...
]

现在我们运行groupBy()

$grouped = $mm->groupBy('birthdate');

现在我们有一个包含模型的集合的集合

$grouped基本上是:

[
'1982-10-10 01:01:01' => [
  0 = MyNamespace\MyModel
 ],
'1981-12-12 01:01:01' => [
  0 = MyNamespace\MyModel
 ],
...
]

所以要映射它只是运行:

$mapped = $grouped->map(
    function ($item, $key) {
      $item = $item->first(); //as item is a collection of models
      $new = [];
      $new['id']                 = $item->id;
      $new['birthdate']          = $item->birthdate;
      return $new;
    }
);

答案 2 :(得分:0)

是的,我认为只有()是相当恼人的,因为似乎没有一种简单的方法在模型集合上使用它(当然是最常见的用例)。我的解决方案是组合map()和only(),如下所示:

$myCollection = MyModel::orderBy('id','desc')->paginate(5)->map(function ($item, $key) {
    return $item->only(['id', 'name']);
});