After a $single_array = array_reduce ($new_array, 'array_merge_recursive', array ());
I get this result
array (size=9)
'key1' => string 'value1'
'key2' => string 'value2'
'key3' => string 'value3'
'key7' =>
array
0 => string 'value7'
1 => string 'value13'
'key8' =>
array
0 => string 'value8'
1 => string 'value14'
'key9' =>
array
0 => string 'value9'
1 => string 'value15'
'key19' => string 'value19'
'key20' => string 'value20'
'key21' => string 'value21'
but i would like that
array
'key1' =>
array
0 => string 'value1'
'key2' =>
array
0 => string 'value2'
'key3' =>
array
0 => string 'value3'
'key7' =>
array
0 => string 'value7'
1 => string 'value13'
'key8' =>
array
0 => string 'value8'
1 => string 'value14'
'key9' =>
array
0 => string 'value9'
1 => string 'value15'
'key19' =>
array
0 => string 'value19'
'key20' =>
array
0 => string 'value20'
'key21' =>
array
0 => string 'value21'
It's probably very simple, but I've been blocking for a few hours.
In short, I would like my array_merge_recursive not to add a key only to the same values, but to add an array[0] also to those which were not the same.
EDIT
The code at the start, the goal being to simplify it and knowing that the values generated as well as the order of the structure can be random.
<?php
$array = array(
'sensors' => array(
'0' => array(
'data' => array(
'0' => array(
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3',
)
)
),
'1' => array(
'data' => array(
'0' => array(
'key7' => 'value7',
'key8' => 'value8',
'key9' => 'value9',
)
)
),
'2' => array(
'data' => array(
'0' => array(
'key7' => 'value13',
'key8' => 'value14',
'key9' => 'value15',
)
)
),
'3' => array(
'data' => array(
'0' => array(
'key19' => 'value19',
'key20' => 'value20',
'key21' => 'value21',
)
)
)
)
);
$new_array = array();
foreach ($array as $element1) {
foreach ($element1 as $j => $element2) {
foreach ($element2 as $element3) {
foreach ($element3 as $element4) {
$new_array[$j] = $element4;
$single_array = array_reduce($new_array, 'array_merge_recursive', array());
}
}
}
}
var_dump($single_array);
You can use array_walk_recursive on the original array:
$result = [];
array_walk_recursive($array, function ($value, $key) use (&$result) {
$result[$key][] = $value;
});
After running this on the example array you provided, $result will be:
[
'key1' => ['value1'],
'key2' => ['value2'],
'key3' => ['value3'],
'key7' => ['value7', 'value13'],
'key8' => ['value8', 'value14'],
'key9' => ['value9', 'value15'],
'key19' => ['value19'],
'key20' => ['value20'],
'key21' => ['value21']
];
Thank you, I found, I was just confusing in_array and is_array. My bad
$array2 = array();
foreach ($single_array as $key1 => $value1) {
if (is_array($value1)) {
foreach($value1 as $key2 => $value2) {
$array2[$key1][$key2] = $value2;
}
}
else {
$array2[$key1][] = $value1;
}
}
var_dump($array2);
Related
What I have:
array(
[
'id' => 12, 'group' => 'abc', 'name' => 'Lorem',
],
[
'id' => 12, 'group' => 'def', 'name' => 'Ipsum',
],
[
'id' => 34, 'group' => 'ghi', 'name' => 'Dolor',
],
[
'id' => 34, 'group' => 'jkl', 'name' => 'Sit',
],
[
'id' => 34, 'group' => 'mno', 'name' => 'Amet',
],
);
What I want:
array (size=2)
12 =>
array (size=2)
'abc' =>
array (size=3)
'id' => int 12
'group' => string 'abc' (length=3)
'name' => string 'Lorem' (length=5)
'def' =>
array (size=3)
'id' => int 12
'group' => string 'def' (length=3)
'name' => string 'Ipsum' (length=5)
34 =>
array (size=3)
'ghi' =>
array (size=3)
'id' => int 34
'group' => string 'ghi' (length=3)
'name' => string 'Dolor' (length=5)
'jkl' =>
array (size=3)
'id' => int 34
'group' => string 'jkl' (length=3)
'name' => string 'Sit' (length=3)
'mno' =>
array (size=3)
'id' => int 34
'group' => string 'mno' (length=3)
'name' => string 'Amet' (length=4)
What I tried:
The obvious:
$sorted = array();
foreach ($products as $product) {
$sorted[$product['id']][$product['group']] = $product;
}
$products = $sorted;
unset($sorted);
But then, in an effort to avoid foreach() loops, and with help of #atomrc's answer to How to group subarrays by a column value?, I came up with this:
$sorted = array_reduce($products, function ($accumulator, $element) {
$accumulator[$element['id']][] = $element;
return $accumulator;
}, []);
array_walk($sorted, function(&$item) {
$item = array_reduce($item, function ($accumulator, $element) {
$accumulator[$element['group']] = $element;
return $accumulator;
}, []);
});
So while the above looks cool and all, it's also much bigger and seemingly more complex than that foreach. This is probably because my experience with array_reduce() is limited. Is there a way to have the array grouped in one go? For example, in the first array_reduce() call.
Personally I don't see an issue with the foreach solution, but if you want to use array_reduce you can simply use the inner code from the foreach loop:
$grouped = array_reduce($products, function ($c, $v) {
$c[$v['id']][$v['group']] = $v;
return $c;
}, []);
print_r($grouped);
The output of this code is the same as your foreach loop.
Note that this (and your foreach loop) won't deal correctly with the situation where there is more than one array with the same id and group values. For example, if we extend $products:
$products[] = [
'id' => 34, 'group' => 'jkl', 'name' => 'Consectetur',
];
Then the first jkl group value gets overwritten by the second. To deal with this you need to make each group an array e.g.
$grouped = array_reduce($products, function ($c, $v) {
$c[$v['id']][$v['group']][] = $v;
return $c;
}, []);
print_r($grouped);
In this case the jkl group then looks like:
[jkl] => Array
(
[0] => Array
(
[id] => 34
[group] => jkl
[name] => Sit
)
[1] => Array
(
[id] => 34
[group] => jkl
[name] => Consectetur
)
)
Demo on 3v4l.org
i have array like :
$options = array (
'af' => 'Afrikaans',
'af_NA' => 'Afrikaans (Namibiƫ)',
'af_ZA' => 'Afrikaans (Suid-Afrika)',
);
i want to add key for the country and for the id like :
$options = array (
[0]=> array (
'id' => 'af'
'name' => 'Afrikaans',
),
[1]=> array (
'id' => 'af_NA'
'name' => 'Afrikaans (Namibie)',
),
)
Make an empty array and then push new arrays onto it after you map your new values correctly.
$new = array();
foreach ($options as $key => $value) {
array_push($new, array("id" => $key, "name" => $value));
}
$options = $new;
You could use a map with lambda:
$result = array_map(function ($id, $name) { return array('id' => $id,'name' => $name); }, array_keys($options), $options);
var_dump($result);
Output:
array (size=3)
0 =>
array (size=2)
'id' => string 'af' (length=2)
'name' => string 'Afrikaans' (length=9)
1 =>
array (size=2)
'id' => string 'af_NA' (length=5)
'name' => string 'Afrikaans (Namibiƫ)' (length=20)
2 =>
array (size=2)
'id' => string 'af_ZA' (length=5)
'name' => string 'Afrikaans (Suid-Afrika)' (length=23)
In PHP, how can I compare two array and get result in a third array ?
This result must contain old and new values. The goal is to display an HTML table with a header like "field | old value | new value" as this, the user can compare all values one by one.
First array :
$array1 = array(
'key1' => array(
'key1.1' => 'value',
'key1.2' => 'value',
),
'key2' => array(
'key2.1' => 'value',
'key2.2' => 'value',
),
'key3' => array(
array('key3.1' => 'value'),
array('key3.2' => 'value'),
),
);
Second array :
$array2 = array(
'key1' => array(
'key1.1' => 'value',
'key1.2' => 'value',
),
'key2' => array(
'key2.1' => 'value',
'key2.2' => 'value',
),
'key3' => array(
array('key3.1' => 'value'),
array('key3.2' => 'value'),
),
);
What I expect :
$results = array(
'key1' => array(
'key1.1' => array(
'old' => 'old_value',
'new' => 'new_value',
),
'key1.2' => array(
'old' => 'old_value',
'new' => 'new_value',
),
),
'key2' => array(
'key2.1' => array(
'old' => 'old_value',
'new' => 'new_value',
),
'key2.2' => array(
'old' => 'old_value',
'new' => 'new_value',
),
),
'key3' => array(
array(
'key3.1' => array(
'old' => 'old_value',
'new' => 'new_value')
),
array(
'key3.1' => array(
'old' => 'old_value',
'new' => 'new_value'),
)
),
);
What I have already tried without success :
function array_diff_assoc_recursive($array1, $array2) {
$exclude = array(
'custom_key'
);
$difference = array();
foreach($array1 as $key => $value) {
if(is_array($value)){
if( !isset($array2[$key]) || !is_array($array2[$key]) ) {
if(!in_array($key,$exclude)){
$difference[$key]['old'] = $value;
$difference[$key]['new'] = $array2[$key];
}
} else {
$new_diff = array_diff_assoc_recursive($value, $array2[$key]);
if(!empty($new_diff))
$difference[$key] = $new_diff;
}
} else if(!array_key_exists($key,$array2) || $array2[$key] !== $value) {
if(!in_array($key,$exclude)){
$difference[$key]['old'] = $value;
$difference[$key]['new'] = $array2[$key];
}
}
}
return $difference;
}
try this code, i'm sure this will work for you
<?php
echo "<pre>";
$array1 = array(
'key1' => array(
'key1.1' => 'aaa',
'key1.2' => 'xxx',
'key1.3' => 'vvv',
),
'key2' => array(
'key2.1' => 'eee',
'key2.2' => 'fff',
'key2.3' => 'ggg',
),
) ;
echo "Array 1: </br>";
print_r($array1);
$array2 = array(
'key1' => array(
'key1.1' => 'aaa',
'key1.2' => 'ddd',
'key1.3' => 'ccc',
),
'key2' => array(
'key2.1' => 'hhh',
'key2.2' => 'fff',
'key2.3' => 'ttt',
),
);
echo "Array 2:</br>";
print_r($array2);
$result='';
foreach($array1 as $key=> $val)
{
foreach($val as $k=> $v)
{
if($v != $array2[$key][$k])
{
$result[$key][$k]['old']= $array2[$key][$k] ;
$result[$key][$k]['new']= $v;
}
}
}
echo "Compared Result: </br>";
echo "<pre>"; print_r($result);
?>
This will Output
Array 1:
Array
(
[key1] => Array
(
[key1.1] => aaa
[key1.2] => xxx
[key1.3] => vvv
)
[key2] => Array
(
[key2.1] => eee
[key2.2] => fff
[key2.3] => ggg
)
)
Array 2:
Array
(
[key1] => Array
(
[key1.1] => aaa
[key1.2] => ddd
[key1.3] => ccc
)
[key2] => Array
(
[key2.1] => hhh
[key2.2] => fff
[key2.3] => ttt
)
)
Compared Result:
Array
(
[key1] => Array
(
[key1.2] => Array
(
[old] => ddd
[new] => xxx
)
[key1.3] => Array
(
[old] => ccc
[new] => vvv
)
)
[key2] => Array
(
[key2.1] => Array
(
[old] => hhh
[new] => eee
)
[key2.3] => Array
(
[old] => ttt
[new] => ggg
)
)
)
Prepare arrays using array_walk_recursive, and combine them. Please note that the original arrays will be changed
array_walk_recursive($array1, function(&$i) { if(!is_array($i)) $i = array('old'=> $i); });
array_walk_recursive($array2, function(&$i) { if(!is_array($i)) $i = array('new'=> $i); });
print_r(array_merge_recursive($array1, $array2));
demo
I have an multidimension array look like this
$input = Array
(
[222] => Array
(
'id' => 222
'val' => 'def'
'more' => 'test'
),
[223] => Array
(
'id' => 223
'val' => 'aaa'
'more' => 'aaa'
),
[224] => Array
(
'id' => 224
'val' => 'aaa'
'more' => 'ddd'
)
[225] => Array
(
'id' => 225
'val' => 'def'
'more' => 'test'
)
);
*Duplicate Because its values of keys val and more duplicated
I want to remove the duplicate value (in this case the $input[222] and $input[225].so the result should only
$res = Array
(
[222] => Array
(
'id' => 222
'val' => 'def'
'more' => 'test'
),
[223] => Array
(
'id' => 223
'val' => 'aaa'
'more' => 'aaa'
),
[224] => Array
(
'id' => 224
'val' => 'aaa'
'more' => 'ddd'
)
);
Anyone know how to do this?
thanks
$newInput = array();
foreach($input as $k => $v) $newInput[$v['val'].$v['more']] = $v;
//You may stop here.
$newInputNum = array();
foreach($newInput as $k => $v) $newInputNum[$v['id']] = $v;
echo "<pre>";print_r($newInputNum );echo "</pre>";
I'm having a problem lately that's driving me crazy. I have a multi-dimensional array like this:
$a = array(
'db' => array(
'0' => array(
'id' => '1',
'name' => 'test',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
'1' => array(
'id' => '2',
'name' => 'test2',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
)
'2' => array(
'id' => '3',
'name' => 'test',
'cat' => array(
'a' => '50',
'b' => '40',
'c' => '90'
),
'canvas' => '1'
)
)
);
And i want to search on it using a function like this: search('canvas = 1');
That would return all the arrays, child of db, that have a key canvas with the value of 1. Or, for example:
search('a = 15');
Would return all arrays that have a key, child of cat, named a and with a value of 15.
$a = array(
'db' => array(
'0' => array(
'id' => '1',
'name' => 'test',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
'1' => array(
'id' => '2',
'name' => 'test2',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
)
);
//checks if array $array contains element with $searchKey key, and $searchVal value
function arrayContains($array, $searchVal, $searchKey) {
if (!is_array($array))
return false;
foreach ($array as $key => $value) {
if ($key === $searchKey && $searchVal === $value)
return true;
if (is_array($value) && arrayContains($value, $searchVal, $searchKey))
return true;
}
return false;
}
function search($a, $search) {
list($searchKey, $searchVal) = explode('=', $search);
$result = array();
foreach($a as $val) {
if (arrayContains($val, $searchVal, $searchKey))
$result[] = $val;
}
return $result;
}
print_r(search($a['db'], "a=15"));
print_r(search($a['db'], "canvas=1"));
Which produces this output(outputs sub-arrays of $a['db'] which contain searched key=>value pair):
Array
(
[0] => Array
(
[id] => 1
[name] => test
[cat] => Array
(
[a] => 15
[b] => 20
[c] => 30
)
[canvas] => 2
)
[1] => Array
(
[id] => 2
[name] => test2
[cat] => Array
(
[a] => 15
[b] => 20
[c] => 30
)
[canvas] => 2
)
)
Array
(
[0] => Array
(
[id] => 3
[name] => test
[cat] => Array
(
[a] => 50
[b] => 40
[c] => 90
)
[canvas] => 1
)
)
Just check the below link if this can help you -
http://php.net/manual/en/function.array-search.php
It contains detailed documentation of php function array_search() and various user codes for searching in multi-dimensional array along with user reviews.
function search($array, $canvas)
{
$result = array();
foreach ($array as $k1 => $v1) {
foreach ($v1 as $k2 => $v2) {
if ($v2['canvas'] == $canvas) {
$result[] = $array[$k1][$k2];
}
}
}
return $result;
}
// $a = your array
print_r(search($a, 1));