I have an array of URLS
Eg:
['support/maintenance', 'support/', 'support/faq/laminator']
How do I sort it base from the number of segments?
Expected result:
['support/faq/maninator', 'support/maintenance, 'support/']
I have an array of URLS
Eg:
['support/maintenance', 'support/', 'support/faq/laminator']
How do I sort it base from the number of segments?
Expected result:
['support/faq/maninator', 'support/maintenance, 'support/']
Use arsort to organize in reverse order, then use usort to sort by string size.
<?php
$arr = ['support/maintenance', 'support/', 'support/faq/laminator'];
function sortOrder($currentValue, $nextValue) {
$totalSegmentsOfTheCurrentIndex = count(preg_split('/\//', $currentValue, -1, PREG_SPLIT_NO_EMPTY));
$totalSegmentsOfTheNextIndex = count(preg_split('/\//', $nextValue, -1, PREG_SPLIT_NO_EMPTY));
// The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
return $totalSegmentsOfTheNextIndex - $totalSegmentsOfTheCurrentIndex;
}
usort($arr, 'sortOrder');
var_export($arr);
You should use usort with custom comparator to count the number of segments after exploding each element by the divider (which is an / in this case):
function comparator($a, $b)
{
if ($a == $b) {
return 0;
}
return count(explode('/', $a)) < count(explode('/', $b)) ? 1 : -1;
}
$array = ['support/maintenance', 'support/', 'support/faq/laminator'];
usort($array, "comparator");
print_r($array);
/**
Array
(
[0] => support/faq/laminator
[1] => support/maintenance
[2] => support/
)
*/
['support/faq/maninator', 'support/maintenance, 'support/'])you can get each url segments count using this function and sort according to this
function count_segment($str) {
$path = trim($str, '/');
return count(explode('/', $path));
}
function arrange($a, $b) {
if ($a == $b) {
return 0;
}
return count_segment($b)-count_segment($a);
}
usort($arr, 'arrange');
try sorting the values in the array using this count of segments
Try this
<?php
$ar = ['support/maintenance', 'support/', 'support/faq/laminator'];
for($i = 0;$i<sizeof($ar);$i++)
{
for($j=$i+1;$j<sizeof($ar);$j++) {
if(sizeof(explode("/",rtrim($ar[$i],"/")))<sizeof(explode("/",rtrim($ar[$j],"/"))))
{
$temp = $ar[$i];
$ar[$i]= $ar[$j];
$ar[$j]=$temp;
}
}
}
print_r($ar);
Try this...
<?php
$array = array('support/maintenance', 'support/', 'support/faq/laminator');
$new = array();
foreach($array as $r){
$key = explode('/',$r);//convert the element into array by '/' occurence.
$key = count(array_filter($key));//remove the empty elements of $key array and count elements.
$new[$key][] = $r; //assign that row to $new[$key] array. This is because of '/' same occurrence.
}
krsort($new); sort $new array by key in descending order
$final = array_merge(...$new); merge $new array. $final array has your result.
echo '<pre>';print_r($final);
?>
I can see you've already chosen the answer and there are 8 another answers, but still, I'll give you more elegant Laravel solution (since you're using the framework). Use the sortByDesc() collection method:
collect($array)->sortByDesc(function($i) { return count(explode('/', $i)); });
One readable line.
You can iterate over result as you would iterate over a usual array. But if you need an array for some reason, add ->toArray() at the end.
If you want to remove / from the beginning and the end of each string when counting segments, add trim($i, '/') into the closure like this explode('/', trim($i, '/'))
You could potentially split each element on '/' then sort the array by the length of sub-arrays then join the sub-arrays on '/'. I am not extremely familiar with php syntax but something like:
for(let i = 0; i < arr.length; ++i) {
arr[i].split('/')
}
// possibly bubble sort depending on length of array by highest length
// same loop with a join instead of a split
To do this we need to remove the / to avoid gettting a wrong value.
Example
var_dump(explode('/', 'support/'));
Result: array(2) { [0]=> string(7) "support" [1]=> string(0) "" }
As you can see it returns 2! which is wrong.
Solution:
To fix this we need to trim the string first. Instead of using count(), explode and trim. We will only use substring_count() and trim().
Here is the whole code:
function sort_url($a, $b)
{
if ($a == $b) {return 0;}
return substr_count(trim($a,'/'),'/') > substr_count(trim($b,'/'),'/') ? -1 : 1;
}
$array = ['support/maintenance', 'support/', 'support/faq/laminator'];
usort($array, "sort_url");
print_r($array);
Output
Array ( [0] => support/faq/laminator [1] => support/maintenance [2] => support/ )