How to move array in multidimensional aray with key value?
I'm using array_push to add values to a multidimensional array. i have an array
$myArray = Array(Array('code' => '1','room' => Array('name' => 'Room-A')),Array('code' =>'1','room' => Array('name' => 'Room-B'
)), Array('code' => '2','room' => Array('name' => 'Vip-1')),Array('code' => '2','room' => Array('name' => 'Vip-2')));
i tried using code like this:
for ($i=0; $i <count($myArray) ; $i++) {
if ($myArray[$i]['code']=='1') {
array_push($myArray[$i]['room'], $myArray[$i]['room']);
}
else{
array_push($myArray[$i]['room'], $myArray[$i]['room']);
}
}
i want the result like this :
Array
(
[0] => Array
(
[code] => 1
[room] => Array
(
[0] => Array
(
[name] => Room-A
)
[1] => Array
(
[name] => Room-B
)
)
)
[1] => Array
(
[code] => 2
[room] => Array
(
[0] => Array
(
[name] => Vip-1
)
[1] => Array
(
[name] => Vip-2
)
)
)
)
Any idea how to join this array?
You can use array_reduce to summarize the array into an associative array using the code as the key. Use array_values to convert the associative array into a simple array.
$myArray = ....
$result = array_values(array_reduce($myArray, function($c, $v){
if ( !isset( $c[ $v['code'] ] ) ) $c[ $v['code'] ] = array( 'code' => $v['code'], 'room' => array() );
$c[ $v['code'] ]['room'][] = $v['room'];
return $c;
},array()));
echo "<pre>";
print_r( $result );
echo "</pre>";
This will result to:
Array
(
[0] => Array
(
[code] => 1
[room] => Array
(
[0] => Array
(
[name] => Room-A
)
[1] => Array
(
[name] => Room-B
)
)
)
[1] => Array
(
[code] => 2
[room] => Array
(
[0] => Array
(
[name] => Vip-1
)
[1] => Array
(
[name] => Vip-2
)
)
)
)
This is the foreach() equivalent of Eddie's answer (I find it easier to read/maintain).
Code: (Demo)
$myArray = [
['code' => '1', 'room' => ['name' => 'Room-A']],
['code' => '1', 'room' => ['name' => 'Room-B']],
['code' => '2', 'room' => ['name' => 'Vip-1']],
['code' => '2', 'room' => ['name' => 'Vip-2']]
];
foreach ($myArray as $row) {
if (!isset($result[$row['code']])) {
$result[$row['code']] = ['code' => $row['code'], 'room' => [$row['room']]];
// ^------------^-- pushed deeper
} else {
$result[$row['code']]['room'][] = $row['room'];
// ^^-- pushed deeper
}
}
var_export(array_values($result));
This question is very similar to many pre-existing questions that want to group by a particular column. I was not able to find an exact duplicate to close with because the requirement of this question is to created a deeper structure to contain the room sub arrays.
Typically I would write:
if (!isset($result[$row['code']])) {
$result[$row['code']] = $row;
to cut down on syntax, but the new output structure must be applied to both the if and the else.
To avoid key duplication/collision, the room subarrays need to be pushed/indexed to a lower level.
In the end, the technique has been demonstrated here many, many times on StackOverflow. You target an element value to group by and use that value as the temporary key as you iterate the input array. Checking if the temporary keys exist or not is the fastest way to determine if a group is new or previously encountered. When you are done, call array_values() to remove the temporary keys (re-index the array).
Related
This my array example
Array
(
[0] => Array ( [_id] => 5f76b1788ee23077dccd1a2c [product] => Array ( [0] => Array ( [_id] => 5d0391a4a72ffe76b8fcc610 ) ) [count] => 1 )
[1] => Array ( [_id] => 5f76b6288ee2300700cd1a3a [product] => Array ( [0] => Array ( [_id] => 5d0391b6a72ffe76b8fcc611 ) ) [count] => 1 )
[2] => Array ( [_id] => 5f76d2488ee23083d3cd1a4a [product] => Array ( [0] => Array ( [_id] => 5d0391b6a72ffe76b8fcc611 ) ) [count] => 1)
)
And i want to group if product value same, like this,
Array
(
[0] => Array ( [_id] => 5f76b1788ee23077dccd1a2c [product] => Array ( [0] => Array ( [_id] => 5d0391a4a72ffe76b8fcc610 ) ) [count] => 1 )
[1] => Array ( [_id] => 5f76b6288ee2300700cd1a3a [product] => Array ( [0] => Array ( [_id] => 5d0391b6a72ffe76b8fcc611 ) ) [count] => 2 )
)
It makes no sense to retain the first level ids since you are arbitrarily trashing some of the first level ids (damaging the relationships) during the merging process.
Instead I recommend that you only isolate the data that is accurately related.
If this output does not serve your needs, then I'll ask for further question clarification.
By assigning temporary keys to your output array, the output array also acts as a lookup array by which you can swiftly check for uniqueness. The "null coalescing operator" (??) sets a fallback value of 0 when an id is encountered for the first time -- this prevents generating any warnings regarding undeclared keys.
Code: (Demo)
$array = [
['_id' => '5f76b1788ee23077dccd1a2c', 'product' => ['_id'=>'5d0391a4a72ffe76b8fcc610'], 'count'=> 1],
['_id' => '5f76b6288ee2300700cd1a3a', 'product' => ['_id'=>'5d0391b6a72ffe76b8fcc611'], 'count'=> 1],
['_id' => '5f76d2488ee23083d3cd1a4a', 'product' => ['_id'=>'5d0391b6a72ffe76b8fcc611'], 'count'=> 1]
];
$productCounts = [];
foreach ($array as $item) {
$productId = $item['product']['_id'];
$productCounts[$productId] = ($productCounts[$productId] ?? 0) + $item['count'];
}
var_export($productCounts);
Output:
array (
'5d0391a4a72ffe76b8fcc610' => 1,
'5d0391b6a72ffe76b8fcc611' => 2,
)
If you insist of the desired output in your question, then it can be as simple and efficient as this...
Code: (Demo)
$result = [];
foreach ($array as $item) {
$productId = $item['product']['_id'];
if (!isset($result[$productId])) {
$result[$productId] = $item;
} else {
$result[$productId]['count'] += $item['count'];
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'_id' => '5f76b1788ee23077dccd1a2c',
'product' =>
array (
'_id' => '5d0391a4a72ffe76b8fcc610',
),
'count' => 1,
),
1 =>
array (
'_id' => '5f76b6288ee2300700cd1a3a',
'product' =>
array (
'_id' => '5d0391b6a72ffe76b8fcc611',
),
'count' => 2,
),
)
You can try the below code it will work for you :-)
<?php
$Myarray = array(['_id'=> '5f76b1788ee23077dccd1a2c', 'product'=> ['_id'=>'5d0391a4a72ffe76b8fcc610'] ,'count'=> 1 ],
['_id'=> '5f76b6288ee2300700cd1a3a', 'product'=> ['_id'=>'5d0391b6a72ffe76b8fcc611'] ,'count'=> 1 ],
['_id'=> '5f76d2488ee23083d3cd1a4a', 'product'=> ['_id'=>'5d0391b6a72ffe76b8fcc611'] ,'count'=> 1 ]
);
$user_array = [];
$temp_array = [];
foreach($Myarray as $temp)
{
$found = array_search($temp['product']['_id'], $temp_array);
if($found !== false)
{
$i = 0;
foreach($user_array as $temp1)
{
if($temp1['product']['_id'] == $temp['product']['_id'])
{
$sum = $temp1['count'] + 1;
$user_array[$i]['count'] = $sum;
}
$i++;
}
}
else
{
array_push($user_array,$temp);
array_push($temp_array,$temp['product']['_id']);
}
}
print_r($user_array);
?>
This will produce below Output
Array ( [0] => Array ( [_id] => 5f76b1788ee23077dccd1a2c [product] => Array ( [_id] => 5d0391a4a72ffe76b8fcc610 ) [count] => 1 ) [1] => Array ( [_id] => 5f76b6288ee2300700cd1a3a [product] => Array ( [_id] => 5d0391b6a72ffe76b8fcc611 ) [count] => 2 ) )
I have an array like below: all the values I am getting one array only, but I don't want this way. This is the best way to do so, in php or jQuery both languages are ok for me
Array
(
[0] => Array
(
[val] => facebook
)
[1] => Array
(
[val] => snapchat
)
[2] => Array
(
[val] => instagram
)
[3] => Array
(
[expenses] => 986532
)
[4] => Array
(
[expenses] => 45456
)
[5] => Array
(
[expenses] => 56230
)
[6] => Array
(
[social_id] => 15
)
[7] => Array
(
[social_id] => 16
)
[8] => Array
(
[social_id] => 17
)
)
and I want to output like this..
$result = array(
array(
"val" => "Facebook",
"expenses" => "84512",
"social_id" => 1
),
array(
"val" => "Instagram",
"expenses" => "123",
"social_id" => 2
)
);
but this should be dynamic, the length of the above array can be varies
You can merge the arrays to one and use array_column to get all vals or expenses in a separate array.
Then foreach one array and build the new array with the key.
//$a = your array
// Grab each column separate
$val = array_column($a, "val");
$expenses= array_column($a, "expenses");
$social_id = array_column($a, "social_id");
Foreach($val as $key => $v){
$arr[] = [$v, $expenses[$key], $social_id[$key]];
}
Var_dump($arr);
https://3v4l.org/nVtDf
Edit updated with the 'latest' version of the array. My code works just fine with this array to without any changes.
to get that array style you can do it by hand for each array
function test(array ...$arr)
{
$result = array();
foreach ($arr as $key => $pair) {
foreach ($pair as $item => $value) {
$result[$item] = $value;
}
}
return $result;
}
$arr1 = test( ['facebook' => 1], ['expenses' => 100]);
print_r($arr1);
/* Array (
[facebook] => 1,
[expenses] => 100
)
*/
$arr2 = test( $arr1, ['more info' => 'info'] );
print_r($arr2);
/* Array (
[facebook] => 1,
[expenses] => 100,
[more info] => info
)
*/
you can pass it any number of
['Key' => 'Pair']
array('Key' => 'Pair')
or even a previous made array and it will add them up into 1 big array and return it
I thought I have some understanding of arrays. But it looks like I have no understanding. Or my head don't want to work. I have arrays:
[0] => Array
(
[key] => Person 1
[values] => Array
(
[0] => Array
(
[0] => 1436821440000,12
)
)
)
[1] => Array
(
[key] => Person 2
[values] => Array
(
[0] => Array
(
[0] => 1437562620000,24
)
)
)
[2] => Array
(
[key] => Person 3
[values] => Array
(
[0] => Array
(
[0] => 1437080040000,10
)
)
)
[3] => Array
(
[key] => Person 1
[values] => Array
(
[0] => Array
(
[0] => 1437082860000,1
)
)
)
[4] => Array
(
[key] => Person 3
[values] => Array
(
[0] => Array
(
[0] => 1437081840000,9
)
)
)
And here is what I want to achieve:
[0] => Array
(
[key] => Person 1
[values] => Array
(
[0] => Array
(
[0] => 1436821440000,12
[1] => 1437082860000,1
)
)
)
[1] => Array
(
[key] => Person 2
[values] => Array
(
[0] => Array
(
[0] => 1437562620000,24
)
)
)
[2] => Array
(
[key] => Person 3
[values] => Array
(
[0] => Array
(
[0] => 1437080040000,10
[1] => 1437081840000,9
)
)
)
How could I remove duplicates and merge data?
The sample input doesn't offer any variation in the data contained in the deept subarrays, so I'll demonstrate the utility of my snippet by adding a little more complexity in the data.
Effectively, each time a new key is encountered, you declare a new row containing the key element and a values element with an empty array. To identify that key as "encountered", the new row is assigned to the result array using the key value as the first level key.
Now that the values subarray is guaranteed to be declared, an inner loop will comb through the deeper arrays and push one or more (all) deep values into the respective values subarray -- in a flat fashion.
Code: (Demo)
$array = [
['key' => 'Person 1', 'values' => [['1436821440000,12']]],
['key' => 'Person 2', 'values' => [['1437562620000,24']]],
['key' => 'Person 3', 'values' => [['1437080040000,10']]],
['key' => 'Person 1', 'values' => [['1437082860000,1'], ['1437082860000,2', '1437082860000,3']]],
['key' => 'Person 3', 'values' => [['1437081840000,9']]],
];
$result = [];
foreach ($array as $row) {
if (!isset($result[$row['key']])) {
$result[$row['key']] = ['key' => $row['key'], 'values' => []];
}
foreach ($row['values'] as $values) {
array_push($result[$row['key']]['values'], ...$values);
}
}
var_export(
array_values($result)
);
Output:
array (
0 =>
array (
'key' => 'Person 1',
'values' =>
array (
0 => '1436821440000,12',
1 => '1437082860000,1',
2 => '1437082860000,2',
3 => '1437082860000,3',
),
),
1 =>
array (
'key' => 'Person 2',
'values' =>
array (
0 => '1437562620000,24',
),
),
2 =>
array (
'key' => 'Person 3',
'values' =>
array (
0 => '1437080040000,10',
1 => '1437081840000,9',
),
),
)
$result_arr = array();
foreach ($arr as $sub_arr)
{
$result_arr = array_merge($result_arr, $sub_arr);
$result_arr = array_unique($result_arr);
}
Below is the print_r($result) result of an $result = array_merge(array($id => $value), array($user => $value), array("Information" => $value)) variable in a piece of PHP code:
Array ( [id] => 1 [user] => 1
[Information] => Array ( [0] => Array ( [name] => 'John' )
[1] => Array ( [family] => 'Goldenberg' )
[2] => Array ( [age] => '21' )))
How to remove the array keys from the "Information" => $value array in PHP to make the output like below:
Array ( [id] => 1 [user] => 1
[Information] => Array ([name] => 'John'
[family] => 'Goldenberg'
[age] => '21'))
Is there any specific function in PHP to complete this task? Thanks a lot for your help.
Your "Information" array is a multidimensional one, having some arrays as the elements, in which there are some "key-value" pairs as "data". You may use the following to reinsert the "data" in the desirable way:
<?php
$info = array( array('name'=>'John'), array('family' => 'Goldenberg'), array('age' => 21));
$out = array();
foreach($info as $arr)
foreach($arr as $key => $val)
$out[$key] = $val;
print_r($out);
?>
Using PHP I need to merge 2 arrays (of equal length into one associative array) here is an excerpt from my current data set:
[1] => Array
(
[0] => C28
[1] => C29
)
[2] => Array
(
[0] => 1AB010050093
[1] => 1AB008140029
)
both elements [1] and [2] are actually a lot longer than just 2 sub-elements (like I said, this is an excerpt).
The deal is that "C28" in the first array corresponds to "1AB010050093" in the second array, and so on... The result I need is to create a new associative array that looks like this:
[1] => Array
(
['ref'] => C28
['part'] => 1AB010050093
)
[2] => Array
(
['ref'] => C29
['part'] => 1AB008140029
)
and so on...
If you are willing to compromise with an array structure like this:
array(
'C28' => '1AB010050093',
'C29' => '1AB008140029'
);
Then you can use the array_combine() (Codepad Demo):
array_combine($refNumbers, $partIds);
Otherwise, you'll need to use a foreach (Codepad Demo):
$combined = array();
foreach($refNumbers as $index => $refNumber) {
if(!array_key_exists($index, $partIds)) {
throw OutOfBoundsException();
}
$combined[] = array(
'ref' => $refNumber,
'part' => $partIds[$index]
);
}
If you're using PHP 5.5+, there is a new method called array_column(), which will get all of the values in a particular column. That could potentially be used, although I think just a simple foreach loop will probably still be your best bet.
How about:
$arr1 = array(
0 => 'C28',
1 => 'C29',
);
$arr2 = array(
0 => '1AB010050093',
1 => '1AB008140029',
);
$result = array();
for ($i=0; $i<count($arr1); $i++) {
$result[] = array('ref' => $arr1[$i], 'part' => $arr2[$i]);
}
print_r($result);
ouptut:
[1] => Array
(
[0] => C28
[1] => C29
)
[2] => Array
(
[0] => 1AB010050093
[1] => 1AB008140029
)