Maybe this is what you are looking for:
-- collection($items)
// I only care about elements having the id = a or id = b
->filter(function ($value, $key) use ($array) {
return isset($array[$value['id']]); // If the key is in the array, the it should be kept in the collection
})
/// Let's now index the collection by the id
->groupBy('id')
// Finally, let's reduce the collection to list of strings per key
->reduce(function ($result, $value) {
return $result . ', ' . $value['title'];
}, '')
I have created this gist for better readability: https://gist.github.com/lorenzo/9198544013a9ca067689
Hope this helps!
On Monday, September 14, 2015 at 10:08:55 AM UTC+2, Walter Vos wrote:
On Monday, September 14, 2015 at 10:08:55 AM UTC+2, Walter Vos wrote:
Hi!I'm having trouble wrapping my head around Collection::reduce. Actually, it feels like I understand how it's supposed to work, but in reality it seems to work differently. I have a collection of entities, from which I'm trying to concat a number of string, based on another array (could probably also be an array, I don't think it would matter much). The array has an ID, the collection has that ID as a foreign ID. I loop through the array, and then in each loop I loop through the collection to find the entities which have a foreign ID matching the ID from the array. Implementing this with Collection::reduce gives a wildly different result from doing it with two foreach() loops. Anyway, here's the code:
public function reducetest() {$this->render('test');$groupby = ['a' => 1, 'b' => 2];$array = [array('id' => 'b', 'title' => 'array_tag_1'),array('id' => 'a', 'title' => 'array_tag_2'),array('id' => 'b', 'title' => 'array_tag_3'),array('id' => 'a', 'title' => 'array_tag_4'),array('id' => 'a', 'title' => 'array_tag_5')];$array_result = array();foreach ($groupby as $key => $value) {$array_result[$key] = '';foreach ($array as $item) {if ($key === $item['id']) {// debug($array_result[$key] . $item['title'] . ", \n");$array_result[$key] .= $item['title'] . ', ';}}$array_result[$key] = trim($array_result[$key], ', ');}debug($array_result);$collection = new Collection([array('id' => 'b', 'title' => 'collection_tag_1'),array('id' => 'a', 'title' => 'collection_tag_2'),array('id' => 'b', 'title' => 'collection_tag_3'),array('id' => 'a', 'title' => 'collection_tag_4'),array('id' => 'a', 'title' => 'collection_tag_5')]);$collection_result = array();foreach ($groupby as $key => $value) {$collection_result[$key] = $collection->reduce(function ($string, $item) use ($key) {if ($key === $item['id']) {// debug($string . $item['title'] . ", \n");return $string . $item['title'] . ', ';}}, '');$collection_result[$key] = trim($collection_result[$key], ', ');}debug($collection_result);}
The code with the two foreach() loops produces this result, as expected:
['a' => 'array_tag_2, array_tag_4, array_tag_5','b' => 'array_tag_1, array_tag_3']
The code that uses the reduce function gives this result, incomprehensibly to me:
['a' => 'collection_tag_4, collection_tag_5','b' => '']
Who can explain to me what I'm not understanding here?
Like Us on FaceBook https://www.facebook.com/CakePHP
Find us on Twitter http://twitter.com/CakePHP
---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+unsubscribe@googlegroups.com.
To post to this group, send email to cake-php@googlegroups.com.
Visit this group at http://groups.google.com/group/cake-php.
For more options, visit https://groups.google.com/d/optout.
No comments:
Post a Comment