PHP sort array through personalized order - php

I need to sort an array, I've done this before but it has been easy because the array had numbers or letters to sort in ascedning/descending or alphabetical order.. In this case i have an array of which each element has 3 values, eg:
array[0]=code=1234
=description='example array'
=orderCode=P
array[1]=code=1235
=description='example array1'
=orderCode=A
.
.
.
Now i need to order theese reading the orderCode value in this order: P,I,B,C,A,S,D.
The way i thought of getting arround it was to add another value to the array and to something like:
if($array[$c]['orderCode'] == 'P')
$array[$c]['newOrderCode'] = 0;
if($array[$c]['orderCode'] == 'I')
$array[$c]['newOrderCode'] = 1;
if($array[$c]['orderCode'] == 'B')
$array[$c]['newOrderCode'] = 2;
or a switch case and then order it by the new value. This would work, but my question is, is there a function I can pass the array to and an orderring string or something?
Thank you,
James

In php 5.3 and above you can use usort with a closure.
$order = array('P','I','B','C','A','S','D');
usort($array, function ($a, $b) use ($order){
return array_search($a["orderCode"], $order) - array_search($b["orderCode"], $order);
});
prior to that you have to create a sorter function
function orderCode_sorter($a, $b){
$order = array('P','I','B','C','A','S','D');
return array_search($a["orderCode"], $order) - array_search($b["orderCode"], $order);
}
usort($array, "orderCode_sorter");

use function user defined and choise sort by key or value you need see all list function here: http://www.php.net/manual/en/array.sorting.php

Related

Sort array object if two key's value number are equal then match to another key value pair

I want to sort php object array in which i have to consider two different keys while sorting, if value of two users is same then consider another key for those values.
given array example
[{'id':'1','total_number':'90','previous_number':'75'},
{'id':'2','total_number':'80','previous_number':'91'},
{'id':'3','total_number':'80','previous_number':'84'},
{'id':'4','total_number':'80','previous_number':'96'},
{'id':'5','total_number':'95','previous_number':'80'}
]
Result array:
[{'id':'5','total_number':'95','previous_number':'80'},
{'id':'1','total_number':'90','previous_number':'75'},
{'id':'4','total_number':'80','previous_number':'96'},
{'id':'2','total_number':'80','previous_number':'91'},
{'id':'3','total_number':'80','previous_number':'84'}
]
You can use a custom sort function to achieve the desired result with the help of usort function in PHP https://www.php.net/manual/en/function.usort.php
// custom sort function
function mySort($a, $b) {
// is total_number same?
if ($a->total_number === $b->total_number) {
// use previous_number to sort
if ($a->previous_number === $b->previous_number) {
return 0;
}
// sort desc
return $a->previous_number > $b->previous_number ? -1 : 1;
}
// sort desc
return $a->total_number > $b->total_number ? -1 : 1;
}
// call the function
usort($array, 'mySort');

Detect if values are repeated and apply order criteria using Laravel and collections

How can I detect if a value is repeated in a collection? And if it repeats, apply a criterion of order for the following value?
I have the following collection where if the "total" value is repeated I have to sort by the value "next" and if the value "next" also repeats, I must sort by the value "subsequent"
Following the criteria of order, it would be as follows:
For now in my code I only have a normal collection:
$sales = Sale::select('total', 'next', 'subsequent', 'person_id')->with('person')->get();
Thanks
You may try this (using Collection::sort() which uses PHP's usort under the hood):
$sales = 'Get result...';
$sorted = $sales->sort(function ($a, $b) {
return strcmp($a->total, $b->total)
?: strcmp($a->next, $b->next)
?: strcmp($a->subsequent, $b->subsequent);
});

php help - sort multidimensional array buy using another array

I hope somebody can help me, I need to order array No.1 based on the position of array no.2 , using the array1->id to array2->products_id
Array No.1
{"products":[{"id": 9847760515,"title":"Some Dress"},{"id": 10769647619,"title":"Shirt"}]}
Array No.2 where the order is: (position":x)
{"collects":[{"id":38447047939,"product_id":10769647619,"position":1,"sort_value":"0000000001"},{"id":25425594499,"product_id":9847760515,"position":3,"sort_value":"0000000003"}]}
foreach ($sorted_array as $product) {
echo $product['name'];
}
Appreciate any help
You can create a function which will take both arrays and order them by whatever format you need it to be in:
/**
* sort_array will take two arrays and will sort the first based on the second
*
* #param $array the array you want to reorder
* #param $order the array with the pattern
*
* #return array_multisort with reordered array
*/
function sort_array(&$array, $order, $dir = SORT_ASC) {
// create an empty array here
$sort = array();
// loop through the main array
foreach ($array as $key => $row) {
$sort[$key] = $row[$order];
}
array_multisort($sort, $dir, $array);
}
Using array_multisort you can "sort multiple or multi-dimensional arrays." For more information on that you can read it on PHP Manual; with further information on how it can be used.
I based this answer with previously answered question on Stack Overflow.
You can use usort function supplying it with order from the second array:
$sort = array_combine(
array_column($array2, 'product_id'),
array_column($array2, 'position')
);
usort($array1, function ($a, $b) use ($sort) {
return $sort[$a['id']] - $sort[$b['id']];
});
We prepare sorting dictionary ($sort) by using array_combine and array_column functions. Pay attention, that in order to use array_column function you have to convert your JSON to an array of arrays (pass true as the second argument of json_decode function).
Here is working demo.

sort array of objects by two fields in php

i have an array of objects like this : http://pastebin.ca/3217309
i want to sort this array to objects with come first then others sort by date
currently I'm using this to sort array
function cmp($a, $b)
{
return strcmp($a->date, $b->date);
}
usort($data, "cmp");
and works good but it only sort array by date and i want to in ordered array objects with pin=1 come first then other objects come after pins.
i hope my question is clear,sorry for bad english !
If you want to sort after an other criteria, you should just add the condition to your sort function:
if ($a->pin != $b->pin) return $a->pin == 1 ? -1 : 1;
this condition only applies for $items with unequal pin properties. Combine your old compare function with this one would result in the following
function cmp($a, $b) {
if ($a->pin != $b->pin) return $a->pin == 1 ? -1 : 1;
return strcmp($a->date, $b->date);
}

Sorting Laravel collection by 2 parameters

It's fun with sorting today! Sigh. I have a big collection of eloquent models that need to be grouped together in the array by one parameter, and ordered in those 'clumps' based on another parameter. This might be hard to explain :(
$master is a collection of Eloquent results, I'm not sure how to write them out here, looping over this I can access all the models functions / relationships
$master = [];
These have 2 properties that need to be the basis for a sort, example of the properties below
//Object 1
$master->carry = 0;
$master->section = 'red';
//Object 2
$master->carry = 1;
$master->section = 'blue';
//Object 3
$master->carry = 0;
$master->section = 'blue';
I want to sort a massive collection of these so that each $master->section is in one 'clump' in the array and inside that 'clump' the $master->carry=0 products are listed last.
From the example above I'd expect Object1, Object3, Object2
I've tried a few different $master->sort() and $master->sortBy() things, but each new sort throws off the old sort :(
I've got the code below currently, which groups up all the colors, but it doesn't order them based on $master->carry yet
$order = array('red', 'blue', 'green');
$master = $master->sort(function ($a, $b) use ($order) {
$pos_a = array_search($a->sectionheader, $order);
$pos_b = array_search($b->sectionheader, $order);
return $pos_a - $pos_b;
});
As I understood, you want to sort your collection the following way:
sort by section in the order stored in $order array
within section move the elements with carry = 0 to the end
You need to pass a function that would implement such logic to $master collection. This function should take 2 arguments (2 elements of collection), compare them and return:
0 if elements are equal
1 if the first element is greater than the second element
-1 if the first element is smaller than the second element
In your case the following callback should work:
$master = $master->sort(function ($a, $b) use ($order) {
// get order of first element's section
$pos_a = array_search($a->section, $order);
// get order of second element's section
$pos_b = array_search($b->section, $order)
// if sections are different the value of carry doesn't matter
// as element's sections are enough to determine which of them is larger
if ($pos_a != $pos_b) {
return $pos_a - $pos_b;
}
// carry values are equal, so consider elements equal
if ($a->carry == $b->carry) {
return 0;
}
if (!$a->carry) {
// if $a->carry is equal to 0 it should be put at the end, so after $b
return 1;
}
if (!$b->carry) {
// if $b->carry is equal to 0 it should be put at the end, so after $a
return -1;
}
// otherwise elements can be considered equal
return 0;
});

Categories