PHP - How To Grouping if value same in array - php

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 ) )

Related

Sequence issue with nested foreach loop php

I have two array. array one and array two. I want to merge these array into single array with key. My output result is valid but sequence is not correct.
Array one
Array
(
[0] => test-685f1e7bc357187e449479d627100102
[1] => test-685f1e7bc357187e449479d627d29390
)
Array two
Array
(
[0] => DF955298-A664-4FA7-9586-FCD4CF977777
[1] => DF955298-A664-4FA7-9586-FCD4CF988888
)
Expected Result
Array
(
[0] => Array
(
[key] => test-685f1e7bc357187e449479d627100102
[uuid] => DF955298-A664-4FA7-9586-FCD4CF977777
)
[1] => Array
(
[key] => test-685f1e7bc357187e449479d627d29390
[uuid] => DF955298-A664-4FA7-9586-FCD4CF988888
)
)
My code is for that result is mentioned below:
$record = array();
foreach ($keys_array as $key => $all_key) {
foreach ($uuid_array as $uuid_key => $all_uuid) {
$record[$key]['key'] = $all_key;
$record[$uuid_key]['uuid'] = $all_uuid;
}
}
My output sequence is not valid. Where is the problem
Array
(
[0] => Array
(
[key] => test-685f1e7bc357187e449479d627100102
[uuid] => DF955298-A664-4FA7-9586-FCD4CF977777
)
[1] => Array
(
[uuid] => test-685f1e7bc357187e449479d627d29390
[key] => DF955298-A664-4FA7-9586-FCD4CF988888
)
)
Simple solution:
$record = array();
foreach ($keys_array as $key => $all_key) {
$record[] = [
'key' => $all_key,
// get value under the same key from `$uuid_array`
'uuid' => $uuid_array[$key],
];
}

How to move array in multidimensional array using key value?

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).

Arrange an array recursively

I'm trying to arrange an array in levels. This is my array:
Array
(
[0] => Array(
[0] => Array(
[id] => 971249312[name] => Wolverine
)
[children] => Array(
[0] => Array(
[0] => Array(
[id] => 735327624[name] => Ciclop
)
[children] => Array()
)
)
)
[1] => Array(
[0] => Array(
[id] => 1926833684[name] => Gambit
)
[children] => Array()
)
[2] => Array(
[0] => Array(
[id] => 51194629[name] => Quicksilver
)
[children] => Array()
)
)
See that the first position of array has 3 elements - this must be the level 0. The first position of these elements must be the level 1. The children of these elements are the next level and so on.
I canĀ“t figure out how to arrange it.
the expected output:
Array
(
["level_1"] => Array
(
[0] => Array
(
[id] => 971249312
[name] => Wolverine
)
[1] => Array
(
[id] => 1926833684
[name] => Gambit
)
[2] => Array
(
[id] => 51194629
[name] => Quicksilver
)
)
["level_2"] => Array
(
[0] => Array
(
[id] => 735327624
[name] => Ciclop
)
)
)
Another recursive tree walk.
I scan the tree 'depth first' so I need to keep track of the current 'level'.
Demonstration at eval.in
Tree scan routine:
/**
* Recursive scan of the tree
*
* #node array Current Node to be processed
* #level integer Current depth of the tree
* output array reference to where to store the details
*
* #return void
*/
function scanNode($node, $level, &$output)
{
$outLevelIdx = 'level_'. $level;
foreach ($node as $idx => $info) {
$parent = current($info);
$output[$outLevelIdx][] = array('id' => $parent['id'], 'name' => $parent['name']);
if (!empty($info['children'])) { // go scan the children
scanNode($info['children'], $level + 1, $output);
}
}
}
Run the scan:
/*
* Output array in here - pass as a reference
*/
$output = array();
// scan the full tree
scanNode($source, 0, $output);
Sample output:
output
Array
(
[level_0] => Array
(
[0] => Array
(
[id] => 971249312
[name] => Wolverine
)
[1] => Array
(
[id] => 1926833684
[name] => Gambit
)
[2] => Array
(
[id] => 51194629
[name] => Quicksilver
)
)
[level_1] => Array
(
[0] => Array
(
[id] => 735327624
[name] => Ciclop
)
)
)
If your desired output is
Array
(
[0] => Array
(
[id] => 971249312
[name] => Wolverine
[children] => Array
(
)
)
[1] => Array
(
[id] => 971249312
[name] => Wolverine
[children] => Array
(
)
)
[2] => Array
(
[id] => 971249312
[name] => Wolverine
[children] => Array
(
)
)
)
Then your code should be
$newArray = [];
foreach ($givenArray as $key => $value) {
$newArray[$key]['id'] = $value[0]['id'];
$newArray[$key]['name'] = $value[0]['name'];
$newArray[$key]['children'] = $value['children'];
}
AS per your desired output
This function used to scan all the node and provide as per your requirment.
OUTPUT
$newArray = [];
myfunction($a, 0,$newArray);
function myfunction($loop, $level, &$newArray) {
$index = "level_".$level;
$i = 0;
foreach ($loop as $key => $value) {
foreach ($value as $key1 => $value1) {
if($key1 !== 'children'){
$newArray[$index][$i] = ['id' => $value1['id'], 'name' => $value1['name']];
$i++;
}
}
if (isset($value['children']) && !empty($value['children'])) {
myfunction($value['children'], $level + 1, $newArray);
}
}
}
print_r($newArray);exit;

PHP merge arrays by value and merge it's sub arrays

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);
}

how can i count an element if it appears more than once in the same array?

how can i count an element if it appears more than once in the same array?
I already tried with array_count_values, but it did not work, is it beacuse i got more than one key and value in my array?
This is my output from my array (restlist)
Array (
[0] => Array ( [restaurant_id] => 47523 [title] => cafe blabla)
[1] => Array ( [restaurant_id] => 32144 [title] => test5)
[2] => Array ( [restaurant_id] => 42154 [title] => blabla2 )
[3] => Array ( [restaurant_id] => 32144 [title] => test5)
[4] => Array ( [restaurant_id] => 42154 [title] => blabla2 )
)
I want it to count how many times the same element appears in my array and then add the counted value to my newly created 'key' called hits in the same array.
Array (
[0] => Array ( [restaurant_id] => 47523 [title] => cafe blabla [hits] => 1)
[1] => Array ( [restaurant_id] => 32144 [title] => test5 [hits] => 2)
[2] => Array ( [restaurant_id] => 42154 [title] => blabla2 [hits] => 2)
)
This is how i tried to do what i wanted.
foreach ($cooltransactions as $key)
{
$tempArrayOverRestaurants[]= $key['restaurant_id'];
}
$wordsRestaruants = array_count_values($tempArrayOverRestaurants);
arsort($wordsRestaruants);
foreach ($wordsRestaruants as $key1 => $value1)
{
$temprestaurantswithhits[] = array(
'restaurant_id' => $key1,
'hits' => $value1);
}
foreach ($restlistas $key)
{
foreach ($temprestaurantswithhits as $key1)
{
if($key['restaurant_id'] === $key1['restaurant_id'])
{
$nyspisestedsliste[] = array(
'restaurant_id' => $key['restaurant_id'],
'title' => $key['title'],
'hits' => $key1['hits']);
}
}
}
I know this is probably a noob way to do what i want but i am still new at php..I hope you can help
Just try with associative array:
$input = array( /* your input data*/ );
$output = array();
foreach ( $input as $item ) {
$id = $item['restaurant_id'];
if ( !isset($output[$id]) ) {
$output[$id] = $item;
$output[$id]['hits'] = 1;
} else {
$output[$id]['hits']++;
}
}
And if you want to reset keys, do:
$outputWithoutKeys = array_values($output);

Categories