Sort nested array using another array with PHP - php

I got this array, comes from database. The order of values is changeable by the users
Array
(
[0] => 14
[1] => 15
[2] => 9
[3] => 13
[4] => 12
...
[n] => n
)
There is another array, which will be extracted to browser:
Array
(
[0] => Array
(
[id] => 1
...
[nr] => 9
...
)
[1] => Array
(
[id] => 2
...
[nr] => 12
...
)
[2] => Array
(
[id] => 3
...
[nr] => 15
...
)
[n] => Array
)
I need to find a way to sort the this second array by nr (not id) and the nr order comes from the first array.
Any ideas?

You can flip the first array in order to know what's the order of the id's:
$order = array_flip($order);
Then you simply use usort to sort the array based on the earlier flipped array:
usort($array, static function(array $a, array $b) use ($order) {
return $order[$a['nr']] <=> $order[$b['nr']];
});

You can just map your values to keys, and use that map to re-order.
<?php
$order =
[
2,
5,
1
];
$items =
[
['o' => 1],
['o' => 5],
['o' => 2],
];
foreach($items as $k => $v) {
$map[$v['o']] = $k;
}
var_export($map);
foreach($order as $o) {
$k = $map[$o];
$result[$k] = $items[$k];
}
var_export($result);
Output:
array (
1 => 0,
5 => 1,
2 => 2,
)array (
2 =>
array (
'o' => 2,
),
1 =>
array (
'o' => 5,
),
0 =>
array (
'o' => 1,
),
)
Assuming there's a one-one mapping.

Related

How add a new a key after using USORT in PHP multidimensional array

I am having one array in that array i want to make ASC order, after that i want insert new column rank then value it will get increase like 1, 2, 3 ...
My Array
$mainArray = [
"key1" => ["name" => "A", "price" => 5],
"key2" => ["name" => "B", "price" => 7],
"key3" => ["name" => "C", "price" => 2],
];
My Code
usort($mainArray, function($a, $b) {
return $a['price'] <=> $b['price'];
});
echo "<pre>";
print_r($mainArray);
I am getting output
Array
(
[0] => Array
(
[name] => C
[price] => 2
)
[1] => Array
(
[name] => A
[price] => 5
)
[2] => Array
(
[name] => B
[price] => 7
)
)
Expected output
Array
(
[0] => Array
(
[name] => C
[price] => 2
[rank] => 1
)
[1] => Array
(
[name] => A
[price] => 5
[rank] => 2
)
[2] => Array
(
[name] => B
[price] => 7
[rank] => 3
)
)
Since your array has been sorted and re-indexed, the rank value is simply the key plus 1. A foreach loop will do what you want:
foreach ($mainArray as $k => &$v) {
$v['rank'] = $k + 1;
}
Demo on 3v4l.org

PHP Filter array of arrays by multiple keys and group the arrays with matching keys

I have an array of arrays, and I want to filter that array by multiple key values, and group the arrays with matching keys if there are any. Example array:
Array
(
[0] => Array
(
[id] => 1
[value] => 11
[quantity] => 14
)
[1] => Array
(
[id] => 2
[value] => 11
[quantity] => 14
)
[2] => Array
(
[id] => 3
[value] => 22
[quantity] => 14
)
[3] => Array
(
[id] => 4
[value] => 22
[quantity] => 14
)
[4] => Array
(
[id] => 5
[value] => 23
[quantity] => 15
)
)
and let's say I want the arrays with matching value and quantity to be grouped in a new array
The desired output would be something like this:
Array
(
[11] => Array
(
[0] => Array
(
[id] => 1
[value] => 11
[quantity] => 14
)
[1] => Array
(
[id] => 2
[value] => 11
[quantity] => 14
)
)
[22] => Array
(
[0] => Array
(
[id] => 3
[value] => 22
[quantity] => 14
)
[1] => Array
(
[id] => 4
[value] => 22
[quantity] => 14
)
)
[23] => Array
(
[0] => Array
(
[id] => 5
[value] => 23
[quantity] => 15
)
)
)
I'm clueless on how to achieve this.
A simple foreach loop over your array to ceate a new array will suffice for this purpose
$new_arr = [];
foreach ($inArray as $arr ) {
$new_arr[$arr['value']][] = $arr;
}
// unset the original array if you are finished with it
// in case it is large and you could make better use
// of the memory for something else
unset($inArray);
If you want to group by the values of multiple keys of the inner arrays, you can join those values together to form the key in your result array.
foreach ($array as $item) {
// combine value and quantity, for example
$key = $item['value'] . '|' . $item['quantity'];
$result[$key][] = $item;
}
just pass an array References and a sort key
function sortBy(&$arr,$by){
$result=array();
foreach($arr as $value){
if(isset($value[$by]))
$result[$value[$by]][]=$value;
}
return $result;
}
Examples
$sorted=sortBy($yourArray,'value'); //by value
$sorted=sortBy($yourArray,'id'); //by Idx
$sorted=sortBy($yourArray,'quantity'); //quantity
You want to group the array keys passing, if I understood correctly.
I usually use the laravel collection library, because it's provided out of the box.
ALthoug, here's my contribution.
Let's try:
function groupArray( $array, $key, $remove = null )
{
$result = array();
foreach (array_unique(array_column($array, $key)) as $value) {
$result[$value] = array_map(function ( $item ) use ( $remove ) {
unset($item[$remove]);
return $item;
}, array_filter($array, function ( $item ) use ( $value, $key ) {
return $item[$key] === $value;
}));
}
return $result;
}
The above function does the job, first we get all the selected key values using the array_column function. THen we do a foreach in the array to filter the array data using the provided key and finally we remove the selected key, if necessary (just because the selected key will be the grouped array keys).
Usage:
$sample = array(
[
'id' => 1,
'value' => 11,
'quantity' => 14
],
[
'id' => 2,
'value' => 11,
'quantity' => 14
],
[
'id' => 3,
'value' => 22,
'quantity' => 14
],
[
'id' => 4,
'value' => 22,
'quantity' => 14
],
[
'id' => 5,
'value' => 23,
'quantity' => 14
],
);
$a = groupArray($sample, 'value', 'value');
$b = groupArray($sample, 'value');
$c = groupArray($sample, 'quantity');

Convert Multidimensional arrays as key and value in PHP

I have 2 Multidimensional arrays as follow:
Array1:
Array (
[0] => Array (
[0] => 2D Design
[1] => 3D Design & Modeling)
[1] => Array ( [0] => Android Developer
[1] => Artificial Intelligence
[2] => Web Developer)
)
Array2:
Array (
[0] => Array (
[0] => 5
[1] => 10)
[1] => Array ( [0] => 2
[1] => 4
[2] => 6)
)
I want to combine the above 2 arrays as key and value as below.
Array (
[0] => Array (
[2D Design] => 5
[3D Design & Modeling] => 10 )
[1] => Array (
[Android Developer] => 2
[Artificial Intelligence] => 4
[Web Developer] => 6 )
)
Please help me to do this. Answers will be appreciated.
use array_combine() function creates an array by using the elements from one "keys" array and one "values" array.
Note: Both arrays must have equal number of elements!
First parameter array taken as key of new array and second parameter taken as value new array .
$new_array=array();
for($i=0;$i<count($arr1);$i++)
{
$new_array[$i]=array_combine($arr1[$i],$arr2[$i]);
}
print_r($new_array);
Output :
Array
(
[0] => Array
(
[2D Design] => 5
[3D Design & Modeling] => 10
)
[1] => Array
(
[Android Developer] => 2
[Artificial Intelligence] => 4
[Web Developer] => 6
)
)
This will work,
$arr1 = array(
0 => array(
0 => "2D Design",
1 => "3D Design & Modeling"),
1 => array(0 => "Android Developer",
1 => "Artificial Intelligence",
2 => "Web Developer",
),
);
$arr2 = array(
0 => array(
0 => 5,
1 => 10,
),
1 => array(0 => 2,
1 => 4,
2 => 6,
),
);
$temp = [];
foreach ($arr1 as $k => &$v) {
foreach ($v as $k1 => &$v1) {
$temp[$k][$v1] = $arr2[$k][$k1];
}
}
print_r($temp);
I have fetched values of first array arr1 as key to temp variable and map it with values of arr2as value to temp array.
This code will work even if index i.e. 0,1,2,3 can be anything.
Here is working code.
Simply make mapped calls of array_combine(). So long as the same positioned rows have the same number of elements in them, everything will work perfectly.
Code: (Demo)
$keys =[
['2D Design', '3D Design & Modeling'],
['Android Developer', 'Artificial Intelligence', 'Web Developer']
];
$values = [
[5, 10],
[2, 4, 6]
];
var_export(
array_map('array_combine', $keys, $values)
);

Array merge on key of two associative arrays in php?

How can I merge these two array together?
Array
(
[0] => Array
(
[id] => 5
[cnt] => 14
)
[1] => Array
(
[id] => 8
[cnt] => 2
)
)
Array
(
[0] => Array
(
[id] => 8
[binding] => hardcover
)
[1] => Array
(
[id] => 5
[binding] => softcover
)
)
The expected result is:
Array
(
[0] => Array
(
[id] => 5
[binding] => softcover
[cnt] => 14
)
[1] => Array
(
[id] => 8
[binding] => hardcover
[cnt] => 2
)
)
The merge of these two array should happen on the [id] value and not on any sort of the array. How can I do this with php in a fast way?
$output = array();
$arrayAB = array_merge($arrayA, $arrayB);
foreach ( $arrayAB as $value ) {
$id = $value['id'];
if ( !isset($output[$id]) ) {
$output[$id] = array();
}
$output[$id] = array_merge($output[$id], $value);
}
var_dump($output);
Optionally if you want to reset output's keys, just do:
$output = array_values($output);
Merge the input arrays, then
Loop the rows and merge associative row data with the array union operator (+). The array union operator should only be used with associative, non-numeric keyed arrays.
The first time that a given id is encountered, there will be no "group" in the result array yet. To avoid a Warning generated by trying to merge row data with an undeclared variable, use the null coalescing operator (??) to fallback to an empty array.
The snippet below will be highly efficient because it makes no iterated function calls.
If you do not want the first level keys in the result array, then call array_values() to re-index the array.
Code: (Demo)
$a1 = [
['id' => 5, 'cnt' => 14],
['id' => 8, 'cnt' => 2],
];
$a2 = [
['id' => 8, 'binding' => 'hardcover'],
['id' => 5, 'binding' => 'softcover'],
];
$result = [];
foreach (array_merge($a1, $a2) as $row) {
$result[$row['id']] = ($result[$row['id']] ?? []) + $row;
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'id' => 5,
'cnt' => 14,
'binding' => 'softcover',
),
1 =>
array (
'id' => 8,
'cnt' => 2,
'binding' => 'hardcover',
),
)

Summing of all elements in the sub array - PHP

I've got the following array as $main_array .Wanted to sum up all the elements in the sub array such as [0]=>6, [1]=>11, [2]=>15.
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[0] => 2
[1] => 4
[2] => 5
)
[2] => Array
(
[0] => 8
[1] => 4
[2] => 3
)
)
Tried the following code.
foreach ($main_array as $key => $value)
$main_array[$key] = Array('1'=>array_sum($value));
print_r($main_array);
But the array structure I got was,
Array
(
[0] => Array
(
[1] => 6
)
[1] => Array
(
[1] => 11
)
[2] => Array
(
[1] => 15
)
)
I'm expecting the array structure as follows.
Array
(
[0] => 6
[1] => 11
[2] => 15
)
Thanks in advance!
When you're calling Array function you're explicitly making an array so you have to remove this from Array('1'=>array_sum($value));
This is how your code should look like
foreach ($main_array as $key => $value)
$main_array[$key] = array_sum($value);
Try this:
foreach ($main_array as $key => $value)
$main_array[$key] = array_sum($value);
That is, place the sum directly in the top level array.
Call array_sum() on every row in your input array. array_map() makes this operation expressive, concise, and doesn't require any new variables to be declared.
Code: (Demo)
$array = [
[1, 2, 3],
[2, 4, 5],
[8, 4, 3],
];
var_export(array_map('array_sum', $array));
Output:
array (
0 => 6,
1 => 11,
2 => 15,
)

Categories