Trying to mimic hierarchy by sorting array in PHP - php

I am trying to sort an array the following way in PHP:
array
0 => id:1203
parent_id: 456
1 => id:456
parent_id:1723
2 => id:1723
parent_id:0
to this:
array
0 => id:1723
parent_id:0
1 => id:456
parent_id:1723
2 => id:1203
parent_id:456
I never sorted an array in PHP before. How would you do it?
Thanks

Is this doing what you want ?
$arr = array(
array('id' => 1203, 'parent_id' => 456),
array('id' => 456, 'parent_id' => 1723),
array('id' => 1723, 'parent_id' => 0)
);
function compare($a, $b) {
if ($a['parent_id'] == 0) return -1;
if ($b['parent_id'] == 0) return 1;
if ($a['id'] == $b['parent_id']) return -1;
if ($b['id'] == $a['parent_id']) return 1;
return 0;
}
usort($arr, 'compare');
print_r($arr);
output:
Array
(
[0] => Array
(
[id] => 1723
[parent_id] => 0
)
[1] => Array
(
[id] => 456
[parent_id] => 1723
)
[2] => Array
(
[id] => 1203
[parent_id] => 456
)
)

I dont see whats the criteria you want to use to sort. Anyway, you could use uasort function , in which you pass a custom function as argument, so in that function you can define whatever criteria you want to order your array. That function would receive 2 arguments (the 2 variables to compare), and you could compare both parent_id (or whatever is you want to compare). To learn what your custom function should return, check this out.
By using uasort instead of usort you can keep your array indexes (as you said in your example).

Related

Array sorting by key value in php [duplicate]

This question already has answers here:
How to Sort a Multi-dimensional Array by Value
(16 answers)
Closed 2 years ago.
I would like to sort below array based on amount but I don't know how. Anyone help me
Array(
[0] => Array
(
[id] => 1
[amount] => 20
)
[1] => Array
(
[id] => 2
[amount] => 30
)
[2] => Array
(
[id] => 3
[amount] => 10
)
)
Something like
PHP7+
usort($array, function($a, $b){
return $a['amount'] <=> $b['amount'];
});
What is <=> (the 'Spaceship' Operator) in PHP 7?
< PHP 7
usort($array, function($a, $b){
if( $a['amount'] == $b['amount'] )
return 0;
else if($a['amount'] > $b['amount'])
return 1;
else
return -1
});
OR you can just subtract them like everyone else...
usort [1] will do the job using a custom comparator function which indexes into the amount property and performs a standard integer comparison for less than/greater than. Sort descending with $b["amount"] - $a["amount"] if you wish.
$data = [
[
"id" => 1,
"amount" => 20
],
[
"id" => 2,
"amount" => 30,
],
[
"id" => 3,
"amount" => 10
]
];
usort($data, function ($a, $b) {
return $a["amount"] - $b["amount"];
});
print_r($data);
Output:
Array
(
[0] => Array
(
[id] => 3
[amount] => 10
)
[1] => Array
(
[id] => 1
[amount] => 20
)
[2] => Array
(
[id] => 2
[amount] => 30
)
)
Use usort.
E.g
function sortByAmount($x, $y) {
return $x['amount'] - $y['amount'];
}
usort($array, 'sortByAmount');
echo "<pre>"; print_r($array);
Use usort function like this (know more about usort click here):
$array = array(array('id'=>1,'amount'=>20),array('id'=>2,'amount'=>30),array('id'=>3,'amount'=>10));
Create custom function like this:
function sortByAmount($x,$y){
return $x['amount']-$y['amount'];
}
Then use usort function like this:
usort($array,'sortByAmount');
// then print
echo"<pre>"; print_r($array);

PHP usort Multi-dimensional array

I'm having trouble getting usort to work and not sure what I'm missing. Below is an example of my array. I want to sort the array based on the value of the sort key.
Array
(
[0] => Array
(
[sort] => 1520546956
[row] => Data lives here
)
[1] => Array
(
[sort] => 1521047928
[row] => Data lives here
)
[2] => Array
(
[sort] => 1520525366
[row] => Data lives here
)
[3] => Array
(
[sort] => 1520525227
[row] => Data lives here
)
My code to try and sort this is:
foreach ($resultsArray as $record)
{
usort($record['sort'], function($a, $b)
{
if ($a == $b)
{
return 0;
}
return ($a < $b) ? -1 : 1;
});
}
However my code seems to be ineffective as the order of the array isn't changing. I feel like I'm close but can't identify what I'm missing. Thank you for any help!
A different approach to accomplish the same functionality is to use array_multisort with the desired combination of sorting flags.
Dataset:
$resultsArray = array(
array('sort'=>1520546956, 'row'=>'row 0 data'),
array('sort'=>1521047928, 'row'=>'row 1 data'),
array('sort'=>1520525366, 'row'=>'row 2 data'),
array('sort'=>1520525227, 'row'=>'row 3 data')
);
array_multisort Example:
$sortValues = array_column($resultsArray, 'sort');
array_multisort($sortValues, SORT_ASC, $resultsArray);
print_r($resultsArray);
Results: https://3v4l.org/NpVIc
Array
(
[0] => Array
(
[sort] => 1520525227
[row] => row 3 data
)
[1] => Array
(
[sort] => 1520525366
[row] => row 2 data
)
[2] => Array
(
[sort] => 1520546956
[row] => row 0 data
)
[3] => Array
(
[sort] => 1521047928
[row] => row 1 data
)
)
Alternatively you can still use usort, but in your function, you need to retrieve the associated array key named sort in order to compare the values.
usort Example:
usort($resultsArray, function($a, $b) {
if ($a['sort'] == $b['sort']) {
return 0;
}
return ($a['sort'] < $b['sort'] ? -1 : 1);
});
print_r($resultsArray);
Results: https://3v4l.org/5nfbc
Modified code to reflect the below as suggested:
usort($resultsArray, function($a, $b) { /* compare $a['sort'] and $b['sort'] */ }
Working perfectly.
$record['sort'] would have to be an array for that to work. Yet still, it does nothing.
I'm pretty sure you want to do this:
<?php
$multiArray = array(
array('sort'=>1520546956, 'row'=>'row 0 data'),
array('sort'=>1521047928, 'row'=>'row 1 data'),
array('sort'=>1520525366, 'row'=>'row 2 data'),
array('sort'=>1520525227, 'row'=>'row 3 data'));
foreach($multiArray as $a){
$numArray[] = $a['sort'];
}
asort($numArray, SORT_NUMERIC);
foreach($numArray as $k => $v){
$resArray[] = $multiArray[$k];
}
print_r($resArray);
?>
It is because php foreach construct works on the copy of the array provided(ie: $resultsArray), where php usort() function references or points to the same array. That is why your code is not working as expected.
If you don't understand this concept I suggest you a good online course by Kevin skoglund (php essential training) in Lynda.com

Sort multidimensional array by keys - fails on duplicates [duplicate]

This question already has answers here:
Sort multi-dimensional array by specific key
(6 answers)
Closed 7 years ago.
I have a function sortBy() that I use to sort multidimensional arrays by a particular key. Here is a sample array:
Array
(
[0] => Array
(
[id] => 4
[type] => 1
[game] => 1
[platform] => 0
[TotalPot] => 7550
)
[1] => Array
(
[id] => 5
[type] => 0
[game] => 2
[platform] => 0
[TotalPot] => 7500
)
)
Here is the function
function sortBy($arr, $field='id', $order=1) {
$a = array();
if ( !is_array($arr) )
return false;
foreach($arr as $subArr) {
$a[$subArr[$field]] = $subArr;
}
if ( $order == 1 ) sort($a);
else rsort($a);
return $a;
}
In this case, calling sortBy($array, 'TotalPot'); would work fine, because the two values for TotalPot are different. However, if you run this example and set both TotalPot fields to $7500, it overwrites the first occurrence with the latter.
What would be the best way to make this function allow for two items with the same value but still keep them in relevant order? I thought about adding another character, an A or 1 to the end, but this seems sloppy and not very predictable, so a better course of action would be greatly appreciated.
You can simplify your code and just use usort(), e.g.
function sortArrayByField(array &$arr, $field = "id", $ASC = TRUE) {
usort($arr, function($a, $b)use($field, $ASC){
if($a[$field] == $b[$field])
return 0;
return $a[$field] > $b[$field] ? $ASC : !$ASC;
});
}
Then just call it like this:
sortArrayByField($array, "TotalPot", TRUE);
print_r($array);
The reason they are getting overwritten is because you're creating an array where the index is the value of the totalPot.
If there are duplicates, then you will only have one array element with the totalPot.
Easiest way is just to usort this:
<?php
$array = [
[
"id" => 4,
"type" => 1,
"game" => 1,
"platform" => 0,
"TotalPot" => 7550
], [
"id" => 5,
"type" => 0,
"game" => 2,
"platform" => 0,
"TotalPot" => 7500
]
];
usort($array, function($a, $b) {
return $a['TotalPot'] - $b['TotalPot'];
});
print_r($array);
Output:
Array
(
[0] => Array
(
[id] => 5
[type] => 0
[game] => 2
[platform] => 0
[TotalPot] => 7500
)
[1] => Array
(
[id] => 4
[type] => 1
[game] => 1
[platform] => 0
[TotalPot] => 7550
)
)
You can also make this a function:
function sortBy($arr, $field='id', $order=1) {
usort($arr, function($a, $b) use ($field, $order) {
if ($order == 1)
return $a[$field] - $b[$field];
else
return $b[$field] - $a[$field];
});
}

compare multi-dimensional arrays and return they keys who's values are different in php from the first array

I have two multi-dimensional array I want to take only those array whose
key values are different from the first array
Here is my two array:
$array1 = Array
(
[0] => Array
(
[id] => 1
[serial] => k-0001
[u_rec_id] => 1
[employer_office] => uouuououou
[job_type] => ouuou
[job_title] => u
[job_appointment_date] => 2013-07-15
[job_duration] => ouu
)
[1] => Array
(
[id] => 2
[serial] => k-0001
[u_rec_id] => 1
[employer_office] => DDC
[job_type] => Manger
[job_title] => Manager
[job_appointment_date] => 2013-07-17
[job_duration] => one year
)
)
and this is my second array
$array2 = Array
(
[0] => Array
(
[id] => 1
[serial] => k-0001
[u_rec_id] => 1
[employer_office] => uouuououou
[job_type] => ouuou
[job_title] => u
[job_appointment_date] => 2013-07-15
[job_duration] => ouu
)
[1] => Array
(
[id] => 2
[serial] => k-0001
[u_rec_id] => 1
[employer_office] => ouo
[job_type] => uououo
[job_title] => udds
[job_appointment_date] => 2013-07-17
[job_duration] => uo
)
);
I tried array_diff and array_diff_assoc it also not worked for me
i get this error
A PHP Error was encountered
Severity: Notice
Message: Array to string conversion
Filename: history/home.php
Line Number: 729
Something like this should get you there, depending on what exactly you want:
$diff = array_udiff($array1, $array2, function (array $a, array $b) {
return (int)array_diff($a, $b);
});
Adjust the comparison function to compare what exactly you want to compare.
http://php.net/array_udiff
foreach, array_unique and possibly array_udiff should help you here.
PHP Manual:
Unique Arrays
Data Comparison
For Each
For a simple array:
$result = array_unique($array);
In your case there's a function from PHP Manual for this:
<?php
function specified_array_unique($array, $value)
{
$count = 0;
foreach($array as $array_key => $array_value)
{
if ( ($count > 0) && ($array_value == $value) )
{
unset($array[$array_key]);
}
if ($array_value == $value) $count++;
}
return array_filter($array);
}
?>
There's been a post that is similar to what you're asking;
Stack Overflow - array_udiff

help sorting this array

So I am looking to sort the multi dimensional array below by "fk_page_id" ascending. Does anyone have any pointers. I think usort() is where I have to look but it seems like I cant find anyone with my specific array structure.
Array
(
[0] => Array
(
[title] => subpage of subpage!
[id] => 5
[long_title] =>
[fk_page_id] => 4
)
[1] => Array
(
[title] => about us subpage
[id] => 4
[long_title] =>
[fk_page_id] => 2
)
[2] => Array
(
[title] => about us
[id] => 2
[long_title] =>
[fk_page_id] => 1
)
)
function cmp($a, $b) {
if($a['fk_page_id'] == $b['fk_page_id']) {
return 0;
} else {
return $a['fk_page_id'] < $b['fk_page_id'] ? -1 : 1;
}
}
usort($yourarray, 'cmp');
if you're using PHP 5.3+:
define(ASC,1);
define(DESC,-1);
function colsort($array,$col,$order=ASC) {
usort(
$array,
function($a,$b) use($col,$order) {
return strcmp($a[$col],$b[$col])*$order;
}
);
return $array;
}
colsort($x,'fk_page_id');

Categories