Flatten a 2d array while preserving numeric associative row keys - php

I need to flatten a 2d array to become a 1d array without losing my numeric 2nd level keys in the process.
Sample data:
[
[2015 => '2015'],
[2016 => '2016'],
[2017 => '2017'],
[2018 => '2018'],
[2019 => '2019'],
[2020 => '2020'],
[2021 => '2021'],
[2022 => '2022'],
[2023 => '2023']
]
Desired output:
[
2015 => '2015',
2016 => '2016',
2017 => '2017',
2018 => '2018',
2019 => '2019',
2020 => '2020',
2021 => '2021',
2022 => '2022',
2023 => '2023'
]
Is it possible to get output like this?

You could do simple foreach loop:
<?php
$years = array(
array(2015 => '2015'),
array(2016 => '2016'),
array(2017 => '2017'),
array(2018 => '2018'),
array(2019 => '2019'),
array(2020 => '2020'),
array(2021 => '2021'),
array(2022 => '2022'),
array(2023 => '2023')
);
foreach($years as $year) {
$key = key($year);
$value = current($year);
$result[$key] = $value;
}
var_dump($result);
Output:
$result = [
2015 => '2015',
2016 => '2016',
2017 => '2017',
2018 => '2018',
2019 => '2019',
2020 => '2020',
2021 => '2021',
2022 => '2022',
2023 => '2023'
];

$theArray = [
[2020 => '2020'], [2021 => '2021'], [2022 => '2022'], [2023 => '2023'],
[2015 => '2015'], [2016 => '2016'], [2017 => '2017'], [2018 => '2018'], [2019 => '2019']
];
$new = [];
foreach ( $theArray as $a) {
$new[key($a)] = $a[key($a)];
}
ksort($new);
print_r($new);
RESULTS
Array
(
[2015] => 2015
[2016] => 2016
[2017] => 2017
[2018] => 2018
[2019] => 2019
[2020] => 2020
[2021] => 2021
[2022] => 2022
[2023] => 2023
)
Of course, it might be more efficient to go to the code that created your original array and amend that to create what you want rather than what it currently does.

I originally closed this page with this canonical page: How to Flatten a Multidimensional Array? After consulting with a moderator, it was advised that this question with narrower requirements should be reopened instead of clarifying the behavior of each answer on the other page which contains a mixture of viable and non-viable solutions for this question.
Here is a rather comprehensive list of viable techniques:
array_reduce() using the union operator with PHP7.4's arrow function syntax generates no variables in the global scope. (Demo)
var_export(
array_reduce($array, fn($result, $row) => $result + $row, [])
);
array_reduce() using array_replace() with PHP7.4's arrow function syntax generates no variables in the global scope. (Demo)
var_export(
array_reduce($array, fn($result, $row) => array_replace($result, $row), [])
);
Converting the data from recursive iterator methods to an array generates no variables in the global scope. Demo
var_export(
iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator($array)))
);
array_walk() requires a global variable to be declared and it is modified by reference in the closure and calls key(). Demo
$result = [];
array_walk($years, function($row) use(&$result) { $k = key($row); $result[$k] = $row[$k]; });
var_export($result);
array_walk_recursive() requires a global variable to be declared and it is modified by reference in the closure without calling key(). Demo
$result = [];
array_walk_recursive($years, function($v, $k) use (&$result) { $result[$k] = $v; });
var_export($result);
Nested foreach() loops generate multiple variables in the global scope, but call no functions. Demo
$result = [];
foreach ($array as $row) {
foreach ($row as $k => $v) {
$result[$k] = $v;
}
}
var_export($result);
There are other viable approaches that use manually scripted recursion and generators but they are less attractive in terms of readability and are likely to be overkill for this task (in my opinion).
Now for the approaches that must not be used because they lose the numeric associative keys in the rows. DON'T use these flattening techniques for this question's data set / requirements.
var_export(array_merge(...$array));
var_export(call_user_func_array('array_merge', $array));
var_export(array_reduce($array, 'array_merge', \[\]));
Laravel's Arr::flatten() method implements manually written recursive code which returns a flat, indexed array -- not appropriate for this case.
Ouzo goodies's Array::flatten() method uses array_walk_recursive() to return an flat, indexed array -- not appropriate for this case.

Related

Array Combine with same year

I hope you guys fine, From last 3-4 hours I try to combine year in the same array set and unset all other arrays which are duplicate (I unable to explain correctly, please check the array example below)., but so far no luck, I tried and I know this isn't the correct way, if anybody has a solution for this please share.
Can somebody tell me how to combine same year in an array and unset other arrays at the same time, I tried but failed, no luck.
Try to do that way, but faild misrably:
foreach ($class as $i=>$class_list){
echo $i;
foreach ($class_list as $key=>$value){
$e=0;
foreach ($class_list as $value2){
if ($value['name']==$value2['name']){
echo 'match';
$class['packages'][$key]['year'][$e]=$value['year'];
}
$e++;
}
}
}
Actual Array:
Array
(
[packages] => Array
(
[0] => Array
(
[name] => atif.ali
[year] => 2019
)
[1] => Array
(
[name] => atif.ali
[year] => 2018
)
[2] => Array
(
[name] => atif.ali
[year] => 2017
)
[3] => Array
(
[name] => khatija.abbas
[year] => 2017
)
)
)
Need output like this:
Array
(
[packages] => Array
(
[0] => Array
(
[name] => atif.ali
[year] => Array
(
[0] 2019
[1] 2018
[2] 2017
)
)
[1] => Array
(
[name] => khatija.abbas
[year] => 2017
)
)
)
P.S: array can be different but "year" and "name" structure always same.
It's probably easiest to just create a new array in the format you require. You can do that by looping over the values inside packages, checking for the existence of the name in the new array, and if it exists, adding the current year to that value. If it doesn't exist, just create a new entry for that name.
$new_array = array('packages' => array());
foreach ($array['packages'] as $value) {
if (($k = array_search($value['name'], array_column($new_array['packages'], 'name'))) !== false) {
$new_array['packages'][$k]['year'][] = $value['year'];
}
else {
$new_array['packages'][] = array('name' => $value['name'], 'year' => array($value['year']));
}
}
print_r($new_array);
Output:
Array
(
[packages] => Array
(
[0] => Array
(
[name] => atif.ali
[year] => Array
(
[0] 2019
[1] 2018
[2] 2017
)
)
[1] => Array
(
[name] => khatija.abbas
[year] => Array (
[0] => 2017
)
)
)
)
Demo on 3v4l.org
Update
If you really want the year field not to be an array when there is only one value, this code will do that for you; it only makes it into an array when a second or subsequent value is seen.
$new_array = array('packages' => array());
foreach ($array['packages'] as $value) {
if (($k = array_search($value['name'], array_column($new_array['packages'], 'name'))) !== false) {
if (is_array($new_array['packages'][$k]['year'])) {
$new_array['packages'][$k]['year'][] = $value['year'];
}
else {
$new_array['packages'][$k]['year'] = array($new_array['packages'][$k]['year'], $value['year']);
}
}
else {
$new_array['packages'][] = $value;
}
}
print_r($new_array);
Demo on 3v4l.org
Try this
$class = ['packages' => [['name' => 'atif.ali', 'year' => 2019], ['name' => 'atif.ali', 'year' => 2018], ['name' => 'atif.ali', 'year' => 2017], ['name' => 'khatija.abbas', 'year' => 2017]]];
$new_class = [];
foreach ($class['packages'] as $key => $class_list) {
if( ! isset($new_class[$class_list['name']])){
$new_class[$class_list['name']] = $class_list;
}else{
if(is_array($new_class[$class_list['name']]['year'])){
$new_class[$class_list['name']]['year'][] = $class_list['year'];
}else{
$prev_year = $new_class[$class_list['name']]['year'];
$new_class[$class_list['name']]['year'] = [$prev_year, $class_list['year']];
}
}
}
$class['packages'] = $new_class;
I see there are some other responses while I wrote my own. First of all here you have the piece of code:
<?php
// Input data
$input = array('packages' => array(
array('name' => 'atif.ali', 'year' => 2019),
array('name' => 'atif.ali', 'year' => 2018),
array('name' => 'atif.ali', 'year' => 2017),
array('name' => 'khatija.abbas', 'year' => 2017),
));
$output = array(); // Create new array to store the final result
foreach ($input['packages'] as $package) { // we are only interested in 'packages', let's iterate over them
$name = $package['name'];
$year = $package['year'];
if (!isset($output[$name])) { // First time we see this name?
$output[$name] = array('name' => $name, 'year' => []); // Let's create an "empty" structure.
}
if (!in_array($year, $output[$name]['year'])) { // First time we see this year for this name?
$output[$name]['year'][] = $year; // Let's add it
}
}
// Reformatting to fit your needs (nest everything under 'packages' and remove the names from resulting dictionary keys)
$output = array('packages' => array_values($output));
var_dump($output);
Let me note the key issues/concepts:
As others suggested: create a new structure for your output. Reusing the same array will probably cause you nightmares. What if you want to later use the original input? Check inmutability and stateless programming.
It is easier if you use a map/dictionary/associative-array for grouping instead of an array itself. It is easier (and faster) to check if a key exists in a map than if an element exists in an array.
All this is using basic php/programming stuff. It can also be achieved by using array_reduce. If you are curious take a look at it :)
Give the code and comments a look and if you have any doubt let me know.
Another option is to create a new result where the key packages already exists. Then use the name as the key so you can check if the key already exists.
If it does not, add a new entry. If it does already exists, index into the new $result converting what is already there to an array so that the first entry which is a string becomes an array.
$arrays = [
"packages" => [
["name" => "atif.ali", "year" => "2019"],
["name" => "atif.ali", "year" => "2018"],
["name" => "atif.ali", "year" => "2017"],
["name" => "khatija.abbas", "year" => "2019"]
]
];
$result = ["packages" => []];
foreach ($arrays["packages"] as $array) {
if(!array_key_exists($array['name'], $result["packages"])) {
$result["packages"][$array['name']] = $array;
continue;
}
$result["packages"][$array['name']]['year'] = (array)$result["packages"][$array['name']]['year'];
$result["packages"][$array['name']]['year'][] = $array['year'];
}
print_r($result);
See a php demo
If you want numerical indexes instead, you could use array_values like this example
I've written this sort of quickly -- I'll look at it again in the morning when I've hopefully had a chance to rest and rethink how to do this with one loop. This seems to work for me. NOTE I did not include the 'packages' key, but the code can be modified by adding it in front of that particular section.
Edit
Had a quick second to think about what I did, perhaps this is what you're looking for:
<?php
$raw = [
[
'name'=>'atif.ali',
'year'=>2018
],
[
'name'=>'atif.ali',
'year'=>2019
],
[
'name'=>'atif.ali',
'year'=>2017
],
[
'name'=>'kahitja.abal',
'year'=>2019
],
[
'name'=>'kahitja.abal',
'year'=>2018
],
[
'name'=>'john.smith',
'year'=>2017
],
[
'name'=>'john.smith',
'year'=>2018
],
];
$map_index = [];
$final = [];
for($i = 0; $i< count($raw); $i++) {
if(!isset($map_index[$raw[$i]['name']])){
$map_index[$raw[$i]['name']] = count($final);
$final[count($final)] = ['name'=>$raw[$i]['name'], 'years'=>[]];
}
$index = $map_index[$raw[$i]['name']];
$final[$index]['years'][]=$raw[$i]['year'];
}
echo '<pre>';
print_r($final);
?>
Here is an example, just build a new array and swap.
<?php
$data =
[
[
'name' => 'Bilbo Baggins',
'year' => 2010
],
[
'name' => 'Bilbo Baggins',
'year' => 2011
],
[
'name' => 'Frodo Baggins',
'year' => 1999
]
];
foreach($data as $item) {
$output[$item['name']]['name'] = $item['name'];
$output[$item['name']]['year'][] = $item['year'];
}
print_r($output);
Output:
Array
(
[Bilbo Baggins] => Array
(
[name] => Bilbo Baggins
[year] => Array
(
[0] => 2010
[1] => 2011
)
)
[Frodo Baggins] => Array
(
[name] => Frodo Baggins
[year] => Array
(
[0] => 1999
)
)
)
If you don't like the new keys, call array_values on the result.

Php multidimentional array convert to one dimentional [duplicate]

This question already has answers here:
Multidimensional array to array
(4 answers)
Closed 6 years ago.
I have an array which consist monthly information as shown below :
[appr] => Array
(
[0] => Array
(
[month] => August
[approd] => 23
)
[1] => Array
(
[month] => September
[approd] => 546
)
[2] => Array
(
[month] => October
[approd] => 234
)
)
I want the output as below
[appr] => Array(
August => 23,
September => 546,
October => 234
)
can anybody help me to achieve this using php.
If you're looking for a simple one-liner solution, use array_column() and array_combine() functions.
Try this:
$array['appr'] = array_combine(array_column($array['appr'], "month"), array_column($array['appr'], "approd"));
Simply loop in your array and create a new array
$array = array(array('month'=>'August','approd'=>'23'),array('month'=>'September','approd'=>'56'),array('month'=>'October','approd'=>'234'),);
$new = array();
foreach($array as $val) {
$new['appr'][$val['month']] = $val['approd'];
}
"One-line" solution using array_column function:
$arr['appr'] = array_column($arr['appr'], 'approd', 'month');
print_r($arr);
The output:
Array
(
[appr] => Array
(
[August] => 23
[September] => 546
[October] => 234
)
)
Another option is to use array_walk_recursive:
<?php
$array = array(
0 => array(
'something',
),
1 => array(
'else',
)
);
// If the keys are unique
$newArray = array();
array_walk_recursive($array, function($v, $k) use (&$newArray) {
$newArray[$k] = $v;
});
// If you have duplicate keys
$newArray = array();
array_walk_recursive($array, function($v) use (&$newArray) {
$newArray[] = $v;
});
And finally output the result:
print_r($newArray);
Resources
array_walk_recursive - Manual

Flatten 3rd level of array to create indexed array of associative rows

I have the following problem:
I have an php array looking like this:
$array = [
[
['sales_count' => '2'],
['customer_id' => '1'],
],
[
['sales_count' => '3'],
['customer_id' => '2'],
]
];
Now if I use json_encode on this array, I get the following result:
[[{"sales_count":"2"},{"customer_id":"1"}],[{"sales_count":"3"},{"customer_id":"2"}]]
However, I'm trying to get the following output: (an array of flat, associative arrays)
[{"sales_count":"2","customer_id":"1"},{"sales_count":"3","customer_id":"2"}]
This is because of the fact that there are two arrays inside your original array on indexes 0 and 1
You need to do something like this
$masterArray = Array (
[0] => Array (
[0] => Array ( [sales_count] => 2 )
[1] => Array ( [customer_id] => 1 )
)
[1] => Array (
[0] => Array ( [sales_count] => 3 )
[1] => Array ( [customer_id] => 2 )
)
);
$json_array = array_merge($masterArray[0], $masterArray[1]);
echo json_encode($json_array);
Syntax for the $masterArray maybe wrong but follow the concept.
on your array should be:
$data = array(
array("sales_count" => 2),
array("customer_id" => 1),
array("sales_count" => 2),
array("customer_id" => 1),
);
json_encode($data);
for you to achieve your expected output.
though if your array is correct you can access your json object by
var data = [
[
{"sales_count":"2"},
{"customer_id":"1"}
],
[
{"sales_count":"3"},
{"customer_id":"2"}
]
];
data[0][0].sales_count will access sales_count = 2 on your 1st array.
I come from VietNam. My English does not good. So, I write this code. I hope this help you.
$arr = array(
0 => array(0 => array('sales_count'=>2),1 => array('customer_id' => 1)),
1 => array(0 => array('sales_count'=>3),1 => array('customer_id' => 2)),
);
$new_arr = array();
foreach($arr as $key => $value){
foreach($value as $kvalue => $vvalue){
$new_arr[] = $vvalue;
}
}
print_r(json_encode($new_arr));
Well, you could restructure them and put them inside a new one. Example:
$new_array = array();
array_walk_recursive($array, function($val, $key) use (&$new_array) {
$new_array[] = array($key => $val);
});
$new_array = json_encode($new_array);
echo '<pre>';
print_r($new_array);
// [{"sales_count":2},{"customer_id":1},{"sales_count":3},{"customer_id":2}]
Or just a simple loop, just simply, push them inside:
$new_array = array();
foreach($array as $values) {
foreach($values as $val) {
$new_array[] = $val;
}
}
echo json_encode($new_array);
Sample output as above.
To flatten the deep associative data in each "row", none of the previous answers work as required. Other techniques provided merely flatten the data to become an array of single-element associative rows (or worse destroy associative relationships while flattening). For the record, dynamically flattening an array's first level is more succinctly coded as array_merge(...$array).
Instead, you must iterate all rows and specifically merge their subarrays. This will flatten the deep structure only so that rows now have two associative elements. THIS is what the question is actually asking for.
Code: (Demo)
echo json_encode(
array_map(
fn($a) => array_merge(...$a),
$array
)
);

explode an array of delimited strings into two arrays

I have the following array:
Array
(
[0] => 10-7
[1] => 11-3
[2] => 11-7
[3] => 12-3
[4] => 12-7
[5] => 13-3
[6] => 13-7
[7] => 14-3
[8] => 14-7
[9] => 15-7
)
that I need to split into two arrays using "-" as delimiter:
Array
(
[0] => 10
[1] => 11
[2] => 11
[3] => 12
[4] => 12
[5] => 13
[6] => 13
[7] => 14
[8] => 14
[9] => 15
)
and
Array
(
[0] => 7
[1] => 3
[2] => 7
[3] => 3
[4] => 7
[5] => 3
[6] => 7
[7] => 3
[8] => 7
[9] => 7
)
Is there anything like array_explode that does what I want? or a combination of php array functions? I'd like to do this without going through my own for/each loop, if possible, or at least minimize having to reinvent the wheel when something (pseudo)in-built is already out there. I already did this with a for loop. But I can't shake the feeling that there's a more elegant way that smartly uses array functions or anything of that kind. Thanks so much, guys.
Additional info:
Not sure if it matters, but I'm actually after the unique values in the resulting two arrays:
Array
(
[0] => 10
[1] => 11
[2] => 12
[3] => 13
[4] => 14
[5] => 15
)
and
Array
(
[0] => 7
[1] => 3
)
The unique values don't need to be sorted, the keys may be preserved or not, and the legal values of the first array range from 0 to 23, while those of the second 1 to 7. However it's possible to have values other than these (0 to 23 and 1 to 7 or even undelimited stray strings or other data types beyond my control), which I would definitely want to throw out.
The magic bullet you're looking for is array_reduce(), e.g. (PHP 5.3+):
list( $left, $right ) = array_reduce( $input,
function( $memo, $item ) {
list( $l, $r ) = explode( '-', $item );
$memo[0][$l] = $memo[1][$r] = true;
return $memo;
},
array( array(), array() )
);
var_dump( array_keys( $left ), array_keys( $right ) );
You can see it in action here.
With PHP <5.3 you'll have to declare the function ahead of time:
function my_reducer( $memo, $item ) {
list( $l, $r ) = // ...
// ... as above ...
}
list( $left, $right ) = array_reduce(
$input, 'my_reducer',
array( array(), array() )
);
http://codepad.org/TpVUIhM7
<?php
$array = array('7-10','7-11','5-10');
foreach($array as $a){list($x[], $y[]) = explode("-", $a);}
print_r(array_unique($x));
print_r(array_unique($y));
?>
Here Is your Solution, Try to implement following code.
Should work for you.
$main_array = array(
'0' => '10-7',
'1' => '11-3',
'2' => '11-7',
'3' => '12-3',
'4' => '12-7',
'5' => '13-3',
'6' => '13-7',
'7' => '14-3',
'8' => '14-7',
'9' => '15-7',
);
foreach($main_array as $key=>$value)
{
$arr_value = explode('-',$value);
$arr_temp1[] = $arr_value[0];
$arr_temp2[] = $arr_value[1];
}
$arr_temp1_unique = array_unique($arr_temp1);
$arr_temp2_unique = array_unique($arr_temp2);
print "<pre>";
print_r($main_array);
print_r($arr_temp1);
print_r($arr_temp2);
print_r($arr_temp1_unique);
print_r($arr_temp2_unique);
print "</pre>";
As far as I know, there is no suitable PHP function that you can use in this situation.
Functions like array_walk() and array_map() result in a single array, not in multiple arrays.
You said you already have tried a sollution with a loop, but for the sake of helping, here is how I would solve this:
//$data contains the array you want to split
$firstItems = array();
$secondItems = array();
foreach($data as $item)
{
list($first, $second) = explode('-', $item, 2);
$firstItems[$first] = true;
$secondItems[$second] = true;
}
//Now you can get the items with array_keys($firstItems) and array_keys($secondItems);
I'm treating the PHP array as a set by setting the keys instead of the values. This makes that you don't have to use array_unique() to get the unique items.
Try:
foreach($old_array as $array){
$new_2d_array = explode('-', $array);
$new_array_1[] = $new_2d_array[0];
$new_array_2[] = $new_2d_array[1];
}
$new_array_1 = array_unique($new_array_1);
$new_array_2 = array_unique($new_array_2);
Okay, if "The unique values don't need to be sorted, the keys may be preserved or not", then I am going to apply the values to the result arrays as both keys and values to ensure uniqueness without any more function calls after the initial loop.
You can use explode() or sscanf(). explode() has a simpler syntax and only requires the glue substring, whereas sscanf() must parse the whole string and therefore needs a more complicated pattern to match with.
If you didn't need uniqueness, you could simply use:
$hours = [];
$days = [];
foreach ($array as $item) {
sscanf($item, '%d-%d', $hours[], $days[]);
}
or
$hours = [];
$days = [];
foreach ($array as $item) {
[$hours[], $days[]] = explode('-', $item);
}
To ensure uniqueness, just use the isolated values as keys as well.
sscanf() allows you to cast the parsed values directly to integers (Demo)
$hours = [];
$days = [];
foreach ($array as $item) {
[0 => $hour, 1 => $day, 0 => $hours[$hour], 1 => $days[$day]] = sscanf($item, '%d-%d');
}
explode() will only produce string-type values. (Demo)
$hours = [];
$days = [];
foreach ($array as $item) {
[0 => $hour, 1 => $day, 0 => $hours[$hour], 1 => $days[$day]] = explode('-', $item);
}
All of the above snippets rely on "array destructuring" syntax instead of calling list(). If you are wondering why the keys are repeated while destructuring, see this post.

ordering array in specific order [duplicate]

This question already has answers here:
Sort multidimensional array by multiple columns
(8 answers)
Closed 5 months ago.
I have following array
Array
(
[0] => Array
(
[label] => Germany
[conversions] => 1
)
[1] => Array
(
[label] => United States
[conversions] => 8
)
[2] => Array
(
[label] => France
[conversions] => 1
)
[3] => Array
(
[label] => China
[conversions] => 1
)
[4] => Array
(
[label] => Philippines
[conversions] => 1
)
[5] => Array
(
[label] => Turkey
[conversions] => 1
)
)
I want to order following array, first by conversions (desc), then by label (asc)
output will have following sequence:
United States
China
France
Germany
Philippines
Turkey
If using >= PHP 5.3...
usort($arr, function($a, $b) {
$diff = $b['conversions'] - $a['conversions'];
if ( ! $diff) {
return strcmp($a['label'], $b['label']);
}
return $diff;
});
It is relatively simple to make it work with < PHP 5.3.
You need to use PHP's usort() function. This allows you to write a function which determines the sort order, so you can sort things into any order you like.
The function will be called repeatedly by the usort() algorithm, and will give you two parameters, being the two elements of the array that it wants to sort at any given moment. Your function should return -1 if the first of those two elements is bigger, +1 if it the second is bigger, and zero if they are to be considered the same for the purposes of the sort.
See the PHP manual page for more info and examples: http://php.net/manual/en/function.usort.php
I preferred array_multisort PHP Manual in my answer below as you can specify the sort order with parameters.
Next to flexibility it should be faster than using usort which has the problem that it's not really parametrized for the sort order, so not re-inventing the wheel as well.
For more comfort, wrap it up into a function to specify the keys as strings (Demo):
$sorted = $multisortByKey($array, 'conversions', SORT_DESC, 'label', SORT_ASC);
as in:
$array = array(
0 => array(
'label' => 'Germany',
'conversions' => 1,
),
1 => array(
'label' => 'United States',
'conversions' => 8,
),
2 => array(
'label' => 'France',
'conversions' => 1,
),
3 => array(
'label' => 'China',
'conversions' => 1,
),
4 => array(
'label' => 'Philippines',
'conversions' => 1,
),
5 => array(
'label' => 'Turkey',
'conversions' => 1,
),
);
$multisortByKey = function(array $a) {
$args = func_get_args();
$a = array_shift($args);
$extract = function($k) use($a) {return array_map(function($v) use($k) { return $v[$k]; }, $a); };
# NOTE: The following check/for-loop is not entirely correct
# as multiple sort parameters per entry are allowed. I leave this
# for practice.
$c = count($args);
if(!$c%2) throw new InvalidArgumentException('Parameter count mismatch');
for($i=0;$i<$c;$i+=2)
$args[$i] = $extract($args[$i]);
$args[] = &$a;
call_user_func_array('array_multisort', $args);
return $a;
};
$sorted = $multisortByKey($array, 'conversions', SORT_DESC, 'label', SORT_ASC);
var_dump($sorted);
try this
$myArray="your array";
<?php
foreach($myArray as $c=>$key) {
$sort_conv[$c] = $key['conversions'];
$sort_lable[$c] = $key['label'];
}
array_multisort($sort_conv, SORT_ASC, $sort_lable, SORT_STRING, $myArray);
print_r($myArray);
?>
You can use usort to provide your own sorting function
usort($a, function($x, $y) {
return $y["conversions"] < $x["conversions"] ? 1 :
($x["conversions"] < $y["conversions"] ? -1 :
strcmp($x["label"], $y["label"]))
);
});
Try the following: (didn't test it, source: PHP Example #3)
foreach ($data as $key => $row) {
$label[$key] = $row['label'];
$conversion[$key] = $row['conversion'];
}
array_multisort($conversion, SORT_DESC, $label, SORT_ASC, $data);

Categories