I have following two multidimensional arrays:
First array:
$array_1_data = Array (
[0] => Array ( [id] => 1 [name] => IT [slug] => it )
[1] => Array ( [id] => 2 [name] => Accounting [slug] => accounting )
)
Second array:
$array_2_data = Array (
[0] => Array ( [cid] => 3 [jid] => 24061 )
[1] => Array ( [cid] => 1 [jid] => 24062 )
)
Expected result:
$some_array = Array (
[0] => Array ( [id] => 1 [name] => IT [slug] => it )
)
I won't mind having [cid] in the result.
I want to intersect these two arrays by [id] of the first array and [cid] of the second array, like inner join in MySQL. I have basic foreach and if else logic for this purpose but speed is a priority now so I'm looking for non-looped solution. For better understanding here is the basic looped solution:
foreach ($array_1_data as $array_1_row ) {
foreach ($array_2_data as $array_2_row ) {
if ($array_2_row['cid'] == $array_1_row['id']) {
//intersection iteration
}
}
}
I tried array_uintersection as follows:
array_uintersect($array_1_data, $array_2_data, function($a1, $a2){
$diff1 = strcasecmp($a1['id'], $a2['cid']);
if ($diff1 != 0) return $diff1;
return 0;
});
But it gives me undefined index 'id'. I checked this question: Comparing two arrays with different key names. First answer for this question gives a looped solution which I want to avoid. Second answer suggests changing SQL structure but I have no control over that. So,
Is there really a non-looped fast solution to this kind of situation?
The solution using array_uintersect_uassoc function:
$result = array_uintersect_uassoc($array_1_data, $array_2_data, function($a, $b){
return strcasecmp($a['id'], $b['cid']);
}, function($a, $b){
return (int) [$a, $b] == ['id', 'cid'];
});
print_r($result);
The output:
Array
(
[0] => Array
(
[id] => 1
[name] => IT
[slug] => it
)
)
According yo your condition: to intersect these two arrays by [id] of the first array and [cid] of the second array, we should consider a key comparison function for those keys only ['id', 'cid'].
Having the needed keys on each comparison step it only remain to compare their values(with value compare function)
http://php.net/manual/en/function.array-uintersect-uassoc.php
DEMO link
Related
I have this array of options, and some value of an internal array is the "ID"
[options] => Array (
[0] => Array (
[id] => 1088
[label] => John
)
[1] => Array (
[id] => 1089
[label] => Peter
)
[2] => Array (
[id] => 1050
[label] => Mary
)
....
On the other hand, I have this array:
$array_sort = array(1089, 1050, 1088, ...);
I would like the options array of the first array is sorted (looking the "id") based on the $array_sort.
I know how to do it in a very dirty way (with a lot of loops and temporary arrays), but I guess there's some smart solution of array_* functions to do this.
Thank you !
You could use array_filter to limit the options to only those in the sorted array, then usort to sort them based on their position in the $array_sort array using array_search:
$sorted = array_filter($options, function($arr) use($array_sort) {
return in_array($arr['id'], $array_sort);
});
usort($sorted, function($a, $b) use($array_sort) {
return array_search($a['id'], $array_sort) - array_search($b['id'], $array_sort);
});
// $sorted should now be the sorted array
I want to merge two arrays in order to get the data as per my requirement.
I am posting my result, please have a look.
First array:
Array
(
[0] => Array
(
[km_range] => 300
[id] => 2
[car_id] => 14782
)
[1] => Array
(
[km_range] => 100
[id] => 3
[car_id] => 14781
)
[2] => Array
(
[km_range] => 300
[id] => 4
[car_id] => 14783
)
)
Second array:
Array
(
[0] => Array
(
[user_id] => 9c2e00508cb28eeb1023ef774b122e86
[car_id] => 14783
[status] => favourite
)
)
I want to merge the second array into the first one, where the value at key car_id matches the equivalent value; otherwise it will return that field as null.
Required output:
<pre>Array
(
[0] => Array
(
[km_range] => 300
[id] => 2
[car_id] => 14782
)
[1] => Array
(
[km_range] => 100
[id] => 3
[car_id] => 14781
)
[2] => Array
(
[km_range] => 300
[id] => 4
[car_id] => 14783
[fav_status] => favourite
)
)
Since the merge is so specific I would try something like this:
foreach ($array1 as $index => $a1):
foreach ($array2 as $a2):
if ($a1['car_id'] == $a2['car_id']):
if ($a2['status'] == "favourite"):
$array1[$index]['fav_status'] = "favourite";
endif;
endif;
endforeach;
endforeach;
You might be able to optimize the code more but this should be very easy to follow...
Another way to achieve this without using the index syntax is to reference the array elements in the foreach by-reference by prepending the ampersand operator:
foreach($firstArray as &$nestedArray1) {
foreach($secondArray as $nestedArray2) {
if ($nestedArray1['car_id'] == $nestedArray2['car_id']) {
$nestedArray1['fav_status'] = $nestedArray2['status'];
}
}
}
You can see it in action in this Playground example.
Technically you asked about merging the arrays. While the keys would be different between the input arrays and the desired output (i.e. "status" vs "fav_status"), array_merge() can be used to merge the arrays.
if ($nestedArray1['car_id'] == $nestedArray2['car_id']) {
$nestedArray1 = array_merge($nestedArray1, $nestedArray2);
}
Playground example.
Additionally the union operators (i.e. +, +=) can be used.
If you want to append array elements from the second array to the first array while not overwriting the elements from the first array and not re-indexing, use the + array union operator1
if ($nestedArray1['car_id'] == $nestedArray2['car_id']) {
$nestedArray1 += nestedArray1;
}
Playground example.
1http://php.net/manual/en/function.array-merge.php#example-5587
I want to check a multi dimensional array for a key value and print its parent array's another key value. This might confuse a bit. But the below example can make it clear. I have a array like this.
Entity Response : Array
(
[0] => Array
(
[type] => FieldTerminology
[relevance] => 0.709023
[count] => 4
[text] => domain name
)
[1] => Array
(
[type] => Company
[relevance] => 0.603375
[count] => 2
[text] => Laravel
)
[2] => Array
(
[type] => Person
[relevance] => 0.548389
[count] => 1
[text] => M. Naveen Kumar
)
I want to check if any array has a key [type] and its value = "Person" , then i want to get its value of the key[text]. In this case I want to print M. Naveen Kumar
You can traverse the array to find it. you can use foreach(), array_walk() and so on.
$o = [];
array_walk($array, function($v) useļ¼&$o){$v['type'] == 'Person' ? $o[] = $v['text'] : '';});
var_dump($o);
Try this
$people = array_filter($array, function($each) { return $each['type'] == 'Person'; });
$names = array_map(function($each) { return $each['name']; }, $people);
How does this work step by step?
Filter the array by type using array_filter
Then map to names using array_map
I have an array that I'm simply trying to order by a score key that contains the value that I'm trying to sort by. The desired results would change the order of the array below to display the index in the following order: [0], [2], [1].
I'm looping through the results which are pulled from a database. I'm creating a key named score and then pushing the $row2 array in to a separate array because if I use mysql_data_seek it gets rid of the score key.
Also it's creating an unwanted key score at the bottom.
How can I best clean this up and make sure the results are ordered high to low as desired?
$my_array = array();
while ($row2 = mysql_fetch_assoc($result2))
{
//score determined here
//$row2['score'] = ...more math, variable is numeric, not a string
array_push($array_page,$row2);
}
Current undesired results...
Array
(
[0] => Array
(
[score] => 7
)
[1] => Array
(
[score] => 2
)
[2] => Array
(
[score] => 4
)
[score] =>
)
Desired results...
Array
(
[0] => Array
(
[score] => 7
)
[2] => Array
(
[score] => 4
)
[1] => Array
(
[score] => 2
)
)
function scoreSort($a, $b){
if($a['score'] == $b['score']) return 0;
return $a['score'] > $b['score'] ? -1 : 1;
}
usort(&$myArray, 'scoreSort');
on php>5.3 you can use inline-functoins:
usort(&$myArray, function($a,$b){ /* ... */ });
Been kind of stuck on this one for a while now, so any help would be appreciated. I have one array (left) that contains a list of elements, the goal is to sort another arrays (right) keys with the values from the left array.
The left array
Array
(
[0] => ID
[1] => FirstName
[2] => LastName
[3] => Address
)
The right array
Array
(
[0] => Array
(
[FirstName] => Pim
[Address] => Finland
[LastName] => Svensson
[ID] => 3
)
[1] => Array
(
[FirstName] => Emil
[Address] => Sweden
[LastName] => Malm
[ID] => 5
)
)
What I'm trying to accomplish would be similar to this
Array
(
[0] => Array
(
[ID] => 3
[FirstName] => Pim
[LastName] => Svensson
[Address] => Finland
)
Anyone? :)
Oh, I'm running php 5.3, if it helps!
$output = array();
foreach ( $right as $array ) {
foreach ( $left as $field ) {
$temp[$field] = $array[$field];
}
$output[] = $temp;
}
You can use uksort() which lets you sort array keys by a user defined function. E.g.:
function sort_by_array($array) {
// create a sorting function based on the order of the elements in the array
$sorter = function($a, $b) use ($array) {
// if key is not found in array that specifies the order, it is always smaller
if(!isset($array[$a])) return -1;
if($array[$a] > $array[$b]) {
return 1;
}
return ($array[$a] == $array[$b]) ? 0 : -1;
};
return $sorter;
}
// $array contains the records to sort
// $sort_array is the array that specifies the order
foreach($array as &$record) {
uksort($record, sort_by_array(array_flip($sort_array)));
}
I make use of the possibility in 5.3 to define functions dynamically and I use array_flip() to transform:
Array
(
[0] => ID
[1] => FirstName
[2] => LastName
[3] => Address
)
to
Array
(
[ID] => 0
[FirstName] => 1
[LastName] => 2
[Address] => 3
)
This makes it easier to compare the keys later.
You must explode the array
Store the array in a variable like this
$array = Array
(
[0] => Array
(
[ID] => 3
[FirstName] => Pim
[LastName] => Svensson
[Address] => Finland
);
and then explode the array
after exploding the array you will get the parameters of the array seperated then you can use implode function the arrange them in anyorder as you wish
I'd take a step back and look at what you really need to do. The array is associative, so you can access the correct element instantly, right? So you don't really need it to be in order, unless you print output with foreach.
I'd suggest one of the following solutions:
If you need the "right" array to be in key-order, then look at the database query / similar and select the columns in the order you need them.
Foreach person you want to print, look up the order in the "left" array, then print the corresponding value of that key in the "right" array.
Well, your question it's uncommon, usually the associative arrays are used to resolve any problems about "position".
Anyway, there are many way to do what you are looking for what are you looking for.
You can use list() but it's position based:
foreach($oldArray as $o)
{
list($firstName,$lastName,$address,$id)=$oldArray;
$newArray[]=array($id,$firstName,$lastName,$address);
}
But the best way to solve your problem it's fill the array directly in the right order instead of re-sort after :)