If array value is repeated in another array, combine both arrays - php

I have several arrays that I want to check for a repeated value and if the value is found to be repeated in one of the other arrays, then combine both of those arrays together.
I give an example below of 2 arrays that have repeated values.
example: the value in purchase_order_number is the same in both arrays below. They are not unique values. But the values in tracking_number are unique.
I want to check if the value in purchase_order_number is repeated in another array. If the same value is found in another array, then combine both of those arrays into 1 array.
I'm trying to get the value in tracking_number and service combined into a single array when the value in purchase_order_number is the same in 2 or more arrays.
Example arrays below.
not combined
array (
'data' =>
array (
15 =>
array (
'type' => 'Tracking',
'id' => 2830143,
'attributes' =>
array (
'tracking_number' => '1Z5270560360309870',
'service' => 'UPS',
'order_id' => 2606218,
'purchase_order_number' => '7249491',
'recipient_attempts' => 1,
),
),
16 =>
array (
'type' => 'Tracking',
'id' => 2830144,
'attributes' =>
array (
'tracking_number' => '1Z5270560361740866',
'service' => 'UPS',
'order_id' => 2606218,
'purchase_order_number' => '7249491',
'recipient_attempts' => 1,
),
),
),
)
Example given below of how I need to combine the two above arrays.
Combined
array (
'data' =>
array (
16 =>
array (
'type' => 'Tracking',
'id' => 2830144,
'attributes' =>
array (
'tracking' =>
array (
0 =>
array (
'tracking_number' => '1Z5270560360309870',
'service' => 'UPS',
),
1 =>
array (
'tracking_number' => '1Z5270560361740866',
'service' => 'UPS',
),
),
'order_id' => 2606218,
'purchase_order_number' => '7249491',
'recipient_attempts' => 1,
),
),
),
)

Here's a reduce based solution with caveats:
$arr['data'] = array_reduce($arr['data'], function ($out, $item) {
// keys we want to extract
static $tracking_keys = ['tracking_number' => '', 'service' => ''];
// yank tracking keys from attributes
$tracking = array_intersect_key($item['attributes'], $tracking_keys);
$item['attributes'] = array_diff_key($item['attributes'], $tracking_keys);
// insert to new array based on order number
$order_no = $item['attributes']['purchase_order_number'];
if (!isset($out[$order_no])) {
$item['attributes']['tracking'] = [$tracking];
$out[$order_no] = $item;
} else {
array_push($out[$order_no]['attributes']['tracking'], $tracking);
}
return $out;
}, []);
Keys in 'data' are not retained and 'id' is set by the first item.

Related

Reorder multidimensional arrays manually by array key name

I have this multidimensional PHP array:
array (
0 =>
array (
'name_lower' => 'apples',
'name' => 'Apples',
),
1 =>
array (
'name_lower' => 'pears',
'name' => 'Pears',
),
2 =>
array (
'name_lower' => 'avocados',
'name' => 'Avocados',
),
3 =>
array (
'name_lower' => 'bananas',
'name' => 'Bananas',
),
)
What I'm trying to manually reorder the arrays inside the multidimensional array and list them in exact the following order:
array (
0 =>
array (
'name_lower' => 'bananas',
'name' => 'Bananas',
),
1 =>
array (
'name_lower' => 'avocados',
'name' => 'Avocados',
),
2 =>
array (
'name_lower' => 'pears',
'name' => 'Pears',
),
3 =>
array (
'name_lower' => 'apples',
'name' => 'Apples',
),
)
It does not follow a pattern to automatically sort the arrays. It needs to be rearranged manually by name. Any ideas?
If you index the array on something unique and set an array with the sort order with those unique values, then you can map the sort order array and extract from the main array:
$sort = array('bananas', 'avocados', 'pears', 'apples');
$array = array_column($array, null, 'name_lower');
$array = array_map(function($v) use($array) { return $array[$v]; }, $sort);

Search and get Key in Multidimensional Array

I have multidimensional array and I need to search for top level key by the value in "add_fields" arrays by "value". I cannot figure out I can achieve the result. Can somebody help me?
I was googling it and found several solutions but I was not able to get any result.
Trying this code
array_search('001001', array_column(array_column($arr, "usr_column_504"), 0)),
but didn't get anything and I need to get top level key. In this example its 0;
array (
0 =>
array (
'id' => 1,
'group_id' => 327,
'volume' => 0,
'vat' => 1,
'order_id' => 1,
'add_fields' =>
array (
1 =>
array (
'field' => 'usr_column_501',
'value' => '',
),
2 =>
array (
'field' => 'usr_column_504',
'value' => '001001',
),
),
),
1 =>
array (
'id' => 2,
'group_id' => 327,
'vat' => 1,
'order_id' => 2,
'add_fields' =>
array (
1 =>
array (
'field' => 'usr_column_501',
'value' => '',
),
2 =>
array (
'field' => 'usr_column_504',
'value' => '001002',
),
),
),
)
If you want the first key where the value of field equals usr_column_504 you could use an outer and an inner foreach.
When the value of field is found, return the $key from the outer foreach.
foreach ($arr as $key => $item) {
foreach ($item["add_fields"] as $addField) {
if ($addField["field"] === "usr_column_504") {
echo $key;
return;
}
}
}
Output
0
Php demo

How can i access all values within a nested array in php by defining a specific key?

I am creating an routing application and get the result as an json array. After transforming it into an php array i get the whole distance and whole duration correctly. Now i need for every value in the key "legs" the distances and durations too but all i did to get the data doesnt work.
The json output of the array looks like this:
array (
'routes' =>
array (
0 =>
array (
'legs' =>
array (
0 =>
array (
'summary' => '',
'weight' => 3741.9,
'duration' => 2912.3, // This value is what i want access
'steps' =>
array (
),
'distance' => 21603.1, // This value is what i want access
),
1 =>
array (
'summary' => '',
'weight' => 3642.1,
'duration' => 2777.4, // This value is what i want access
'steps' =>
array (
),
'distance' => 21611.8, // This value is what i want access
),
),
'weight_name' => 'routability',
'weight' => 7384,
'duration' => 5689.700000000001, // This value i can acesss
'distance' => 43214.899999999994, // This value i can acesss too
),
),
'waypoints' =>
array (
0 =>
array (
'hint' => '',
'distance' => 16.78277948979663, // This value is what i want access
'name' => 'Weg',
'location' =>
array (
0 => 11.4623,
1 => 50.7126,
),
),
1 =>
array (
'hint' => '',
'distance' => 16.62835508134535,
'name' => 'Weg',
'location' =>
array (
0 => 12.6069,
1 => 51.5398,
),
),
2 =>
array (
'hint' => '',
'distance' => 16.78277948979663,
'name' => 'Weg',
'location' =>
array (
0 => 12.343,
1 => 51.576,
),
),
),
'code' => 'Ok',
)
The whole distance (43214.8) and whole duration (5689.7) i get by the following code:
foreach($res2['routes'] as $item)
{
$distances = array_push_assoc($distances, $item['distance'], $item['duration']);
}
In order to get the distances and durations i did the following:
foreach($res2['routes']['legs'] as $item)
{
$durations = array_push_assoc($durations , "DUR", $item['duration']);
}
How can i get the distances and durations from "legs"? Why doenst work $res2['routes']['legs']?
Thank you!
Do notice the the "legs" array exists in index 0 of the "routes" array so looping on it will require using $res2['routes'][0]['legs'].
Morever, notice that using array_push_assoc in loop with the same hard-coded key (as "DUR" in your example) will override the key each time so your data gets lost - you better change it to:
foreach($res2['routes'][0]['legs'] as $item) {
$durations[] = $item['duration'];
}

How to extract unique values from this multidimensional array?

How to extract unique values from this array.
I've tried another suggestion...
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
However because of the unix timestamp it wont work.
Im looking to extract only the second array index unique value and its array so should be left with..
// expected final
array(
2 => array(...),
3 => array(..)
)
$arr = array (
0 =>
array (
2 =>
array (
'date' => 1438173658,
'user' => 'admin',
),
),
1 =>
array (
2 =>
array (
'date' => 1438007944,
'user' => 'admin',
),
),
2 =>
array (
3 =>
array (
'date' => 1437746969,
'user' => 'supes',
),
)
)
Thanks.
Might be a simpler way, but here is one:
$result = array_intersect_key($arr,
array_unique(array_map(function($v) {
return current($v)['user'];
},
$arr)));

php getting unique values of a multidimensional array [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
php multi-dimensional array remove duplicate
I have an array like this:
$a = array (
0 => array ( 'value' => 'America', ),
1 => array ( 'value' => 'England', ),
2 => array ( 'value' => 'Australia', ),
3 => array ( 'value' => 'America', ),
4 => array ( 'value' => 'England', ),
5 => array ( 'value' => 'Canada', ),
)
How can I remove the duplicate values so that I get this:
$a = array (
0 => array ( 'value' => 'America', ),
1 => array ( 'value' => 'England', ),
2 => array ( 'value' => 'Australia', ),
4 => array ( 'value' => 'Canada', ),
)
I tried using array_unique, but that doesn't work due to this array being multidimensional, I think.
Edit: I also need this array to be multi-dimensional and in this format, I can't flatten it.
array_unique is using string conversion before comparing the values to find the unique values:
Note: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same. The first element will be used.
But an array will always convert to Array:
var_dump("Array" === (string) array());
You can solve this by specifying the SORT_REGULAR mode in the second parameter of array_unique:
$unique = array_unique($a, SORT_REGULAR);
Or, if that doesn’t work, by serializing the arrays before and unserializing it after calling array_unique to find the unique values:
$unique = array_map('unserialize', array_unique(array_map('serialize', $a)));
Here :)
<?php
$a = array (
0 => array ( 'value' => 'America', ),
1 => array ( 'value' => 'England', ),
2 => array ( 'value' => 'Australia', ),
3 => array ( 'value' => 'America', ),
4 => array ( 'value' => 'England', ),
5 => array ( 'value' => 'Canada', ),
);
$tmp = array ();
foreach ($a as $row)
if (!in_array($row,$tmp)) array_push($tmp,$row);
print_r ($tmp);
?>
Use SORT_REGULAR flag.
$unique_array = array_unique($a, SORT_REGULAR);
I'm not sure why it helps but it does. At least with php 5.3

Categories