Reputation:
I would like to split an array:
$o = json_decode('[{"id":"1","color":"green"},{"id":"2","color":"green"},{"id":"3","color":"yellow"},{"id":"4","color":"green"}]');
based on the color attribute of each item, and fill corresponding sub arrays
$a = array("green", "yellow", "blue");
function isGreen($var) {
return ($var->color == "green");
}
$greens = array_filter($o, "isGreen");
$yellows = array_filter($o, "isYellow");
// and all possible categories in $a..
My $a
has a length > 20, and could increase more, so I need a dynamic way instead of writing functions by hand.
There doesn't seem to exist a function array_split()
to generate all filtered arrays
or else I might need a kind of lambda function.
Upvotes: 4
Views: 649
Reputation: 4948
If you need more arguments you could use this function:
function splitArray($array, $params) {
$result = array();
foreach ($array as $item) {
$status = true;
foreach ($params as $key => $value) {
if ($item[$key] != $value) {
$status = false;
continue;
}
}
if ($status == true) {
$result[] = $item;
}
}
return $result;
}
$greensAndID1 = splitArray($o, array('color' => 'green', 'id' => 1));
Upvotes: 0
Reputation: 72672
You could do something like:
$o = json_decode('[{"id":"1","color":"green"},{"id":"2","color":"green"},{"id":"3","color":"yellow"},{"id":"4","color":"green"}]');
$greens = array_filter($o, function($item) {
if ($item->color == 'green') {
return true;
}
return false;
});
Or if you want to create something really generic you could do something like the following:
function filterArray($array, $type, $value)
{
$result = array();
foreach($array as $item) {
if ($item->{$type} == $value) {
$result[] = $item;
}
}
return $result;
}
$o = json_decode('[{"id":"1","color":"green"},{"id":"2","color":"green"},{"id":"3","color":"yellow"},{"id":"4","color":"green"}]');
$greens = filterArray($o, 'color', 'green');
$yellows = filterArray($o, 'color', 'yellow');
In my second example you could just pass the array and tell the function what to filter (e.g. color or some other future property) on based on what value.
Note that I have not done any error checking whether properties really exist
Upvotes: 6
Reputation: 21466
I would not go down the road of creating a ton of functions, manually or dynamically.
Here's my idea, and the design could be modified so filters are chainable:
<?php
class ItemsFilter
{
protected $items = array();
public function __construct($items) {
$this->items = $items;
}
public function byColor($color)
{
$items = array();
foreach ($this->items as $item) {
// I don't like this: I would prefer each item was an object and had getColor()
if (empty($item->color) || $item->color != $color)
continue;
$items[] = $item;
}
return $items;
}
}
$items = json_decode('[{"id":"1","color":"green"},{"id":"2","color":"green"},{"id":"3","color":"yellow"},{"id":"4","color":"green"}]');
$filter = new ItemsFilter($items);
$greens = $filter->byColor('green');
echo '<pre>';
print_r($greens);
echo '</pre>';
Upvotes: 1