I have an initial array:
$arr0 = array(
0 => array(
'a' => 1,
'b' => 1
)
1 => array(
'a' => 2,
'b' => 1
)
2 => array(
'a' => 3,
'b' => 2
)
3 => array(
'a' => 4,
'b' => 3
)
4 => array(
'a' => 5,
'b' => 3
)
);
I wish to divide it into separate arrays depending on its members' value of the field 'b', like so:
// $arr1 contains $arr0[0] and $arr0[1] because their value of 'b' is 1.
$arr1 = array(
0 => array(
'a' => 1,
'b' => 1
)
1 => array(
'a' => 2,
'b' => 1
)
);
// $arr2 contains $arr0[2] because its value of 'b' is 2.
$arr2 = array(
0 => array(
'a' => 3,
'b' => 2
)
);
// $arr3 contains $arr0[3] and $arr0[4] because their value of 'b' is 3.
$arr3 = array(
0 => array(
'a' => 4,
'b' => 3
)
1 => array(
'a' => 5,
'b' => 3
)
);
Now, the field 'b' can have any natural number for value, so it is not always three resulting arrays that I will need.
I have found a related question (and answers) here, but my problem is specific because I don't know in advance what original values 'b' has, and how many of different values there are.
Any ideas?
(edit: $arr3 was written as $arr1)
foreach ($arr0 as $value) {
${"arr" . $value['b']}[] = $value;
}
// $arr1, $arr2 and $arr3 are defined
There is magic in the second line, which dynamically builds a variable name. However, that way of programming is really unwieldy; you would do better to make the results into yet another array, like this:
foreach ($arr0 as $value) {
$allarr[$value['b']][] = $value;
}
// $allarr is defined
foreach ($arr0 as $val) {
$b = $val ['b'];
if (!$arr$b) $arr$b = array();
$arr$b[] = $val;
}
Related
This question already has answers here:
How to Flatten a Multidimensional Array?
(31 answers)
Closed 5 months ago.
I have following array keys values:
$arrData = array
(
array(
'a' => 'test',
'c' => 1,
'd' => 2,
'e' => 'B'
),
array(
'c' => 1,
'd' => 2,
'e' => 'B'
),
array(
'b' => 'test2',
'c' => 1,
'd' => 2,
'e' => 'B'
)
);
So here I need to merged array into single with combining missing keys with single value array.
Can someone please help to get following output in single array?
$arrData = array
(
array(
'a' => 'test',
'b' => 'test2',
'c' => 1,
'd' => 2,
'e' => 'B'
)
);
Thanking in advance!
Just merge them and then sort on the key:
$arrData = array_merge(...$arrData);
ksort($arrData);
Instead of ... you can use:
$arrData = call_user_func_array('array_merge', $arrData);
If you really want the result to be multi-dimensional, then:
$arrData = [$arraData];
//or
$arrData = array($arrData);
You can use array_reduce (or a simple foreach loop) to merge each of the subsequent array values with the first one:
$out = array_reduce($arrData, function ($c, $v) { return array_merge($c, $v); }, array());
print_r($out);
$out = array();
foreach ($arrData as $arr) {
$out = array_merge($out, $arr);
}
print_r($out);
Output (for both examples):
Array (
[a] => test
[c] => 1
[d] => 2
[e] => B
[b] => test2
)
If you want to keep the keys in alphabetical order, you can use ksort:
ksort($out);
print_r($out);
Array (
[a] => test
[b] => test2
[c] => 1
[d] => 2
[e] => B
)
Demo on 3v4l.org
Using array_walk and ksort
$res=[];
array_walk($arrData, function($v,$k) use(&$res){
$res = array_merge($res,$v);
});
ksort($res);
OR
You can use foreach and array_column
$keys = ['a','b','c','d','e'];
$res=[];
foreach($keys as $val){
$res[$val] = array_column($arrData, $val)[0];
}
print_r($res);
Live Demo
<?php
$arrData = array
(
array(
'a' => 'test',
'c' => 1,
'd' => 2,
'e' => 'B'
),
array(
'c' => 1,
'd' => 2,
'e' => 'B'
),
array(
'b' => 'test2',
'c' => 1,
'd' => 2,
'e' => 'B'
)
);
$result_array = array();
foreach($arrData as $ad){
foreach($ad as $key=>$value){
if(!array_key_exists($key,$result_array)){
$result_array[$key] = $value;
}
}
}
print_r($result_array);
?>
This is my json data as an array, and it is in the file data.json, I tried to parse the data using php, but I am not able show the result using a for loop.
array (
'data' =>
array (
0 =>
array (
'a' => 3222,
'b' => 3,
),
1 =>
array (
'a' => 3221,
'b' => 3,
),
2 =>
array (
'a' => 2215,
'b' => 2,
),
3 =>
array (
'a' => 2214,
'b' => 2,
),
4 =>
array (
'a' => 3218,
'b' => 2,
),
5 =>
array (
'a' => 3217,
'b' => 3,
),
6 =>
array (
'a' => 3216,
'b' => 3,
),
7 =>
array (
'a' => 1235,
'b' => 1,
),
8 =>
array (
'a' => 1234,
'b' => 1,
),
9 =>
array (
'a' => 1233,
'b' => 1,
),
10 =>
array (
'a' => 3213,
'b' => 3,
)
)
I want to display only the data, which is "b=3" which contains the maximum value of "a".
Here is my code, which displays all the results of "a" as a string. All the data is shown as a list.
<?php
$json = file_get_contents('data.json');
$data = json_decode($json,true);
$q = $data['data'];
$length = count($q);
for ($i = 0; $i<$length ; $i++){
if ($q[$i]['b']==3){
$pc = $q[$i]['a'];
echo $pc;
echo "<br>";
}
}
This is not the result I was expected.
One way to solve this could be to check the current value of $pc against the latest value;
If that is higher, then overwrite it:
$q = $data['data'];
$length = count($q);
$max = 0;
for ($i = 0; $i<$length ; $i++){
if ($q[$i]['b']==3){
$pc = $q[$i]['a'];
if ($pc > $max) {
$max = $pc;
}
}
}
echo $max; //3222
Another option could be to use array_map and max:
$result = max(array_map(function($x){
if($x['b'] === 3) return $x['a'];
}, $q
));
echo $result; //3222
I have two arrays. One array consists of Id & another array consists of the values & keys. For example. I have a variable called Fruit_id, which consists of:
array(
'fruit_id' => array(
(int) 0 => '3',
(int) 1 => '4'
)
)
and another array called fruits, which consists of:
array(
'values' => array(
(int) 1 => ' Apple',
(int) 2 => 'Banana',
(int) 3 => 'Orange',
(int) 4 => 'Mango'
),
'keys' => array(
(int) 0 => (int) 1,
(int) 1 => (int) 2,
(int) 2 => (int) 3,
(int) 3 => (int) 4
)
)
So, based on fruit_id, I want to have Orange & Mango stored in a variable. How can this be achieved?
as per my understanding you can try below code
$fruits = array();
foreach ($array1['fruit_id'] as $key1 => $value1)
{
foreach ($array2['values'] as $key2 => $value2)
{
if ($value1 == $key2)
{
$fruits[$value1] = $value2;
}
}
}
print_r($fruits);
This will return Array ( [3] => Orange [4] => Mango )
Let me know if this helps you out or any changes needed
You could achieve this easily without even using any loop. Use array_filter() instead.
$array1 = array("fruit_id" => array(3, 4));
$array2 = array(
"values" => array(1 => "Apple",2 => "Banana",3 => "Orange", 4 => "Mango"),
"keys" => array(1,2,3,4)
);
/* Filter elements from $array2['values'] whose keys are present in $array1['fruit_id'] */
$result = array_filter($array2['values'], function($v, $k) use ($array1){
return in_array($k, $array1['fruit_id']);
}, ARRAY_FILTER_USE_BOTH);
echo implode(' & ', $result); // Convert array to string separated by '&'
I've 2 arrays nested to 4 or 5 levels coming from an external source (so, I can't, and don't want to manually, change the structure if possible). I've simplified the problem below but keep in mind that the structures are out of my control so I need a somewhat generic solution.
$x = array (
'one' =>
array (
'two' => 2,
'three' =>
array (
0 => 3,
),
),
);
$y = array (
'one' =>
array (
'three' =>
array (
0 => 3,
),
'four' => 4,
'five' => 5,
),
'six' => 6
);
I want to merge these and get:
array (
'one' =>
array (
'two' => 2,
'three' =>
array (
0 => 3,
),
'four' => 4,
'five' => 5,
),
'six' => 6
)
I've tried all of the following and none give me exactly the above:
var_dump($x+$y);
var_dump(array_merge($x,$y));
var_dump(array_merge_recursive($x,$y));
var_dump($y+$x);
var_dump(array_merge($y,$x));
var_dump(array_merge_recursive($y,$x));
So, I guess I need some custom code to do the merge. What would it be? Keeping it generic and simple.
function array_merge_recursive_unique($array1, $array2) {
if (empty($array1)) return $array2; //optimize the base case
foreach ($array2 as $key => $value) {
if (is_array($value) && is_array(#$array1[$key])) {
$value = array_merge_recursive_unique($array1[$key], $value);
}
$array1[$key] = $value;
}
return $array1;
}
Please search before post. This is a duplicate of merge-2-arrays-with-no-duplicated-keys
Use Zend\StdLib\ArrayUtils::merge(), this method is used for merging config arrays in ZF2 and do that you want.
See:
https://github.com/zendframework/zf2/blob/master/library/Zend/Stdlib/ArrayUtils.php
$arr1 = array('a' => '1', 'b' => 'blah', 'c' => 'whatever...',
'aa' => '2', 'bb' => 'lbha', 'cc' => 'everwhat...', 'dd' => 'bingo',
'aaa' => '3', 'bbb' => 'halb', 'ccc' => 'revetahw...');
In the array I have three different index lengths a,b and c are all 1 in length. aa,bb,cc and dd are all 2 in length. And aaa,bbb and ccc are all 3 in length.
What I'm trying to do is find the index (group by length) with the most elements and the greatest length.
so I would use aa,bb,cc,dd as they have 4 elements, this would return the index length of 2.
I want to know how I can get the 2?
Here is what I'm trying but it's not working
foreach($arr1 as $key => $data) {
$index_length_arr[strlen($key)] = $index_length_arr[$key] + 1;
}
Results:
Array
(
[1] => 1
[2] => 1
[3] => 1
)
Expected Output:
Array
(
[1] => 3
[2] => 4
[3] => 3
)
Then I could see that index (with the length of 2) had the most elements:
'aa' => '2', 'bb' => 'lbha', 'cc' => 'everwhat...', 'dd' => 'bingo',
$array = array_count_values(array_map('strlen',array_keys($arr1)));
Should give ya what ya want.
Edit:
Your original code was fine except you have to change the = .... to $index_length_arr[strlen($key)]
You were using two different keys.
I'd recommend creating your own (or using a library that already does it). It'd be something like this (did not test it):
function groupBy($array, $function)
{
$dictionary = [];
if ($array) {
foreach ($array as $item) {
$dictionary[$function($item)][] = $item;
}
}
return $dictionary;
}
Using it like this:
$usersByAge = groupBy($users, function ($age) { return $user->age; } );
I would highly recommend using lstrojny's functional-php https://github.com/lstrojny/functional-php which includes a group() function along with a host of other useful functional programming concepts.
$arr1 = array('a' => '1', 'b' => 'blah', 'c' => 'whatever...',
'aa' => '2', 'bb' => 'lbha', 'cc' => 'everwhat...', 'dd' => 'bingo',
'aaa' => '3', 'bbb' => 'halb', 'ccc' => 'revetahw...');
$tmpArray = array();
foreach ($arr1 AS $key => $val) {
if (empty($tmpArray)) {
$tmpArray[strlen($key)] = 0;
}
$tmpArray[strlen($key)]++;
}
print_r($tmpArray);
Gets you your expected result.