How do I sort a multidimensional array? [duplicate] - php

This question already has answers here:
How to Sort a Multi-dimensional Array by Value
(16 answers)
Closed 5 years ago.
I'm tracking how many words appear in the description of my products and created a multidimensional array that is keeping track but I need to sort them by the most found keywords to the lowest. I have this array and I want to be able to sort it by the "count" key:
Array
(
[KOM1-K182924DA] => Array
(
[count] => 1
[words] => Array
(
[4] => cotton
)
)
[PVH1-U2666001] => Array
(
[count] => 2
[words] => Array
(
[2] => cotton
[5] => briefs
)
)
[GEO2-K2345TF] => Array
(
[count] => 1
[words] => Array
(
[4] => red
)
)
[KOM1-K182871HK] => Array
(
[count] => 3
[words] => Array
(
[4] => cotton
[5] => nylon
[6] => blue
)
)
)
So the result would look like this:
Array
(
[KOM1-K182871HK] => Array
(
[count] => 3
[words] => Array
(
[4] => cotton
[5] => nylon
[6] => blue
)
)
[PVH1-U2666001] => Array
(
[count] => 2
[words] => Array
(
[2] => cotton
[5] => briefs
)
)
[KOM1-K182924DA] => Array
(
[count] => 1
[words] => Array
(
[4] => cotton
)
)
[GEO2-K2345TF] => Array
(
[count] => 1
[words] => Array
(
[4] => red
)
)
)
How can I do this? I've tried multiple solutions that I found on stackoverflow but none of them have worked for me. I've tried the solution on here Sort Multi-dimensional Array by Value. I'm using PHP 5.6 so I tried this:
usort($myArray, function($a, $b) {
return $a['order'] - $b['order'];
});
But it's not returning an array, instead it returns the "sku" and a digit.

Extract the count column into a single dimension, sort that descending and sort the original array by that:
array_multisort(array_column($myArray, 'count'), SORT_DESC, $myArray);

you may use array_multisort or usort
working solution:
function sortBySubValue($array, $value, $asc = true, $preserveKeys = false)
{
if ($preserveKeys) {
$c = array();
if (is_object(reset($array))) {
foreach ($array as $k => $v) {
$b[$k] = strtolower($v->$value);
}
} else {
foreach ($array as $k => $v) {
$b[$k] = strtolower($v[$value]);
}
}
$asc ? asort($b) : arsort($b);
foreach ($b as $k => $v) {
$c[$k] = $array[$k];
}
$array = $c;
} else {
if (is_object(reset($array))) {
usort($array, function ($a, $b) use ($value, $asc) {
return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} - $b->{$value}) * ($asc ? 1 : -1);
});
} else {
usort($array, function ($a, $b) use ($value, $asc) {
return $a[$value] == $b[$value] ? 0 : ($a[$value] - $b[$value]) * ($asc ? 1 : -1);
});
}
}
return $array;
}
sortBySubValue($array, 'count', false, true);

Related

How to sort array by child value of dynamic indexes?

How to sort this array by sort_order keeping in mind that initial two keys are dynamic, I tried with ksort but this didn't help me much.
[3] => Array
(
[3] => Array
(
[name] => text2
[id] => 3
[sort_order] => 2
)
[4] => Array
(
[name] => text6
[id] => 4
[sort_order] => 6
)
)
[2] => Array
(
[2] => Array
(
[name] => text5
[id] => 2
[sort_order] => 5
)
)
you can use usort function
usort($array, function($item1, $item2) { return $item1['sort_order'] >= $item2['sort_order'];});
you have to flat your array then use the usort function
$result = [];
foreach ($array as $list) {
$result = array_merge($result, $list);
}
usort($result, function($item1, $item2) { return $item1['sort_order'] >= $item2['sort_order'];});
echo '<pre>';
print_r($result);

How to sort 2 arrays by the value [duplicate]

This question already has answers here:
How to Sort a Multi-dimensional Array by Value
(16 answers)
Closed 7 years ago.
I have this array:
Array (
[order] => Array ( [0] => 2 [1] => 1 )
[eventid] => Array ( [0] => id_1 [1] => id_2 )
)
Now I would like to get:
Array (
[order] => Array ( [0] => 1 [1] => 2 )
[eventid] => Array ( [0] => id_2 [1] => id_1 )
)
Basically I would like to sort arrays by value of order.
You will need to use the usort function to be able to do this. (See the documentation)
I would recommend another Array structure though, something like this:
Array (
[0] => Array ( [order] => 2, [eventid] => id_x )
[1] => Array ( [order] => 1, [eventid] => id_y )
)
Then you could a function like this one to sort your array (PHP 5.3 or greater):
function array_sort_by(&$array, $key, $descending = false) {
$sortByKey =
function ($a, $b) use ($key, $descending) {
if ($a[$key] === $b[$key]) {
return 0;
}
$return = $a[$key] < $b[$key] ? -1 : 1;
return ($descending ? -1 * $return : $return);
};
usort($array, $sortByKey);
}
You would then call the following:
array_sort_by($yourArray, 'order');
You can use asort. While it can cover your case, usort might be a better solution in the long run.
$arr = Array (
"order" => Array ( 0 => 6, 1 => 1,2=>43),
"eventid" => Array ( 0 => 5, 1 => 1,2=>54,3=>0)
);
foreach ($arr as $key => &$value) {
asort($value);
}

Sort a 3 level multi-dimension array by value in PHP

Here is the array,
array(
[0] => Array
(
[IdRedeemProduct] => Item-A
[RedeemOptions] => Array
(
[0] => Array
(
[Points] => 1000
)
[1] => Array
(
[Points] => 2000
)
[2] => Array
(
[Points] => 43000
)
)
[ProductType] => 1
)
[1] => Array
(
[IdRedeemProduct] => Item-B
[RedeemOptions] => Array
(
[0] => Array
(
[Points] => 6200
)
[1] => Array
(
[Points] => 53000
)
)
[ProductType] => 1
)
)
most of the usort examples are just 2 level dimension array. I couldn't find any example for 3 level.
In this case i wanted to sort the smallest points to show first. Item-A will be the first and Item-B will be the 2nd.
foreach ($filteredResults as $key => $row)
{
foreach ($row['RedeemOptions'] as $key2 => $option) {
$vc_array_name[$key] = $option['Points'];
}
}
array_multisort($vc_array_name, SORT_ASC, $filteredResults);
this is working...
Try this:
function sort_2d_desc($array, $key) {
usort($array, function($a, $b) use ($key) {
return strnatcasecmp($b[$key], $a[$key]);
});
return $array;
}
$a = [];
foreach($arr as $key => $val){
$a[$key] = $this->sort_2d_desc($val['RedeemOptions'], 'Points');
}
$newArr = [];
foreach($arr as $key => $val){
$newArr[] = ['IdRedeemProduct' => $val['IdRedeemProduct'], 'RedeemOptions' => $a, 'ProductType' => $val['ProductType']];
}
print_r($newArr);

Sort multidimensional array by value unique array keys

I want to sort Multi dimensional array based up on the value, please check following array,
Array
(
[1] => Array
(
[70000] => Aceh
)
[2] => Array
(
[70024] => Sumatera Utara
)
[3] => Array
(
[70058] => Barat
)
[4] => Array
(
[70078] => Riau
)
[5] => Array
(
[70091] => Jambi
)
)
I want it to be like this after sort, please check below array.
Array
(
[1] => Array
(
[70000] => Aceh
)
[2] => Array
(
[70024] => Barat
)
[3] => Array
(
[70058] => Jambi
)
[4] => Array
(
[70078] => Riau
)
[5] => Array
(
[70091] => Sumatera Utara
)
)
Can any one help me with the good solution please. Thank you!.
Very strange output that you're after. Use something like this:
function weirdSort($array) {
$out = [];
$keys = [];
$values = [];
foreach($array as $k => $v) {
$values[] = $v;
$keys[] = $k;
}
usort($values);
foreach($keys as $i => $key) {
$out[] = [$key => $values[$i];
}
return $out;
}
I don't know this way is good or bad but I got wanted output by usort
function cmp($a, $b) {
if ($a[key($a)] == $b[key($b)]) return 0;
return ($a[key($a)] > $b[key($b)]) ? 1 : -1;
}
usort( $levelOneArray, 'cmp' );
print_r($levelOneArray);

2d array - group by value and sum up same keys' values

Hello and thanks for taking the time to look at my question.
My current problem is that, I have the following array ($topics_percentage):
Array
(
[0] => Array
(
[id] => 8989
[cat] => Category 1
[completed] => 0
)
[1] => Array
(
[id] => 8919
[cat] => Category 2
[completed] => 1
)
[2] => Array
(
[id] => 8913
[cat] => Category 2
[completed] => 1
)
[3] => Array
(
[id] => 8947
[cat] => Category 1
[completed] => 1
)
[4] => Array
(
[id] => 8949
[cat] => Category 3
[completed] => 1
)
)
What I need to get, is something like the following example:
Array
(
[Category 1] => Array
(
[noncompleted] => 1
[completed] => 1
)
[Category 2] => Array
(
[completed] => 2
)
[Category 3] => Array
(
[completed] => 1
)
)
What I've tried so far is this:
$class_array = [];
foreach ($topics_percentage as $v) {
$complete = $v['completed'];
$class_array[$v['cat']][] =
($complete == 0 ? 'noncompleted' : 'completed');
}
Which returns the following:
Array
(
[Category 1] => Array
(
[0] => noncompleted
[1] => completed
)
[Category 2] => Array
(
[0] => completed
[1] => completed
)
[Category 3] => Array
(
[0] => completed
)
)
I'm weak when it comes to arrays, and can't figure out the logic.
Thanks in advance.
Try this:
$values = array_unique(array_map(
function ($v) { return $v['cat']; },
$array
));
$result = array();
foreach ($values as $val) {
$flt = array_filter($array, function ($v) use ($val) {
return $v['cat'] == $val;
});
$cnt = count(array_filter($array, function ($v) use ($val) {
return $v['completed'];
}));
$result[$val] = array(
'completed' => $cnt,
'noncompleted' => count($flt) - $cnt
);
}
Try this:
foreach ($topics_percentage as $v) {
$complete = $v['completed'];
if ($complete == 1) {
$class_array[$v['cat']]['completed']++;
} else {
$class_array[$v['cat']]['uncompleted']++;
}
}
You should, of course, preinitialize the array before you count up values, but the basic idea is to use array cells as numeric values to be added or substracted from.

Categories