php - Sort array of strings by 3rd-to-last character based on another array then sort on whole strings

144

I have an array like:

$unsorted = Array(
"0" =>"3470U11",
"1" =>"3470E11",
"2" =>"3470S13",
"3" =>"3470G11",
"4" =>"3470S12",
"5" =>"3470S11",
"6" =>"3470E12",
"7" =>"3470U12",
"8" =>"3470G13",
"9" =>"3470G12",
"10" =>"3470E13",
"11" =>"3470U13"
);

And a priority array like this:

$sortBy = array('G','D','S','U','E','T','A','L');

I need to sort the array by thesubstr($value,-3,1) in the order listed in$sortBy so the result becomes like:

$sorted = Array(
"0" => "3470G11",
"1" => "3470G12",
"2" => "3470G13",
"3" => "3470S11",
"4" => "3470S12",
"5" => "3470S13",
"6" => "3470U11",
"7" => "3470U12",
"8" => "3470U13",
"9" => "3470E11",
"10" =>"3470E12",
"11" =>"3470E13"
);
527

Answer

Solution:

usort

(PHP 4, PHP 5, PHP 7) usort — Sort an array by values using a user-defined comparison function

$unsorted = Array(
"0" =>"3470U11",
"1" =>"3470E11",
"2" =>"3470S13",
"3" =>"3470G11",
"4" =>"3470S12",
"5" =>"3470S11",
"6" =>"3470E12",
"7" =>"3470U12",
"8" =>"3470G13",
"9" =>"3470G12",
"10" => "s3470E13",
"11" => "s3470U13"
);

//$a and $b -> two elts of the array
function cmp ($a,$b){

    $substring_a = substr($a, -3,1);
    $substring_b = substr($b, -3,1);
    
    $sortArr = array('G','D','S','U','E','T','A','L');
    
    $key_a = array_search($substring_a, $sortArr);
    $key_b = array_search($substring_b, $sortArr);
    
    if($key_a == $key_b){
        return strcmp(substr($a, -2),substr($b, -2));
        
    }   
    return $key_a > $key_b;

}

usort($unsorted, "cmp");
print_r($unsorted);
407

Answer

Solution:

You can use a user defined compare function when sorting. usort() if you want the indexes to be rearanged or uasort() if you want to keep the keys as they are.

Your callback function can be something like this:

public function sortCallback($item1, $item2){
     $orderArr = array('G','D','S','U','E','T','A','L');

     $iItem1 = array_search( substr($item1,-3,1), $orderArr );
     $iItem2 = array_search( substr($item2,-3,1), $orderArr );

     if($iItem1 == $iItem2){
          return 0;
     }

     return ($iItem1 < $iItem2) ? -1 : 1;
}

See on php.net:

145

Answer

Solution:

Try to someting like this....

$unsorted = Array(
        "0" =>"3470U11",
        "1" =>"3470E11",
        "2" =>"3470S13",
        "3" =>"3470G11",
        "4" =>"3470S12",
        "5" =>"3470S11",
        "6" =>"3470E12",
        "7" =>"3470U12",
        "8" =>"3470G13",
        "9" =>"3470G12",
        "10" => "s3470E13",
        "11" => "s3470U13"
    );

    $sortArr = array('G','D','S','U','E','T','A','L');

    foreach ($sortArr as $key => $value) {
        foreach ($unsorted as $key1 => $value1) {
            $val = substr($value1,-3,1);
            if ($val === $value) {
                $sortArrFin[] = $value1;
            }
        }
    }
    foreach ($sortArrFin as $key3 => $value3) {
        $val1 = substr($value3,-2);
        $newSortArr[] = $val1;
    }
    sort($newSortArr);
    $uniqueArr = array_unique($newSortArr);
    foreach ($uniqueArr as $key4 => $value4) {
        foreach ($sortArrFin as $key5 => $value5) {
            $val2 = substr($value5,-2);
            if ($val2 === $value4) {
                $Final[] = $value5;
            }
        }
    }
    foreach ($sortArr as $key6 => $value6) {
        foreach ($Final as $key7 => $value7) {
            $val3 = substr($value7,-3,1);
            if ($val3 === $value6) {
                $Last[] = $value7;
            }
        }
    }
    echo "<pre>";
    print_r($Last);
834

Answer

Solution:

Assuming:

  1. your prioritizing array is an exhaustive list of potential letters and
  2. you want to apply a secondary sorting rule which compares whole strings alphabetically and
  3. you are running PHP7.4 or higher...

This is a concise, accurate, modern, professional way to implement the required sorting. I am callingusort() which first sorts on the third-last letter based on the original index of the$sortBy array. The "Elvis operator" (?:) separates the first rule from the second rule. The whole string comparision is the fallback sorting rule if the first rule results in a tie.

Code: (Demo)

$unsorted = [
    "3470U11",
    "3470E11",
    "3470S13",
    "3470G11",
    "3470S12",
    "3470S11",
    "3470E12",
    "3470U12",
    "3470G13",
    "3470G12",
    "3470E13",
    "3470U13"
];

$sortBy = ['G', 'D', 'S', 'U', 'E', 'T', 'A', 'L'];
$priority = array_flip($sortBy);

usort(
    $unsorted,
    fn($a, $b) =>
        ($priority[substr($a, -3, 1)] <=> $priority[substr($b, -3, 1)])
        ?: $a <=> $b
);

var_export ($unsorted);

Output:

array (
  0 => '3470G11',
  1 => '3470G12',
  2 => '3470G13',
  3 => '3470S11',
  4 => '3470S12',
  5 => '3470S13',
  6 => '3470U11',
  7 => '3470U12',
  8 => '3470U13',
  9 => '3470E11',
  10 => '3470E12',
  11 => '3470E13',
)
954

Answer

Solution:

try this : PHP usort() will the suitable for that

<?php 
   $sortBy_Index = array_flip($sortBy);
   sort($data, SORT_STRING);
   $FlippedData = array_flip($data);
   $compare = function($a, $b) use (&$sortBy_Index, &$FlippedData) {
       $aid = substr($a, -3, 1);$bid = substr($b, -3, 1);
       $ai = $sortBy_Index[$aid];$bi = $sortBy_Index[$bid];

       if ($ai === null and $bi === null) {
          return $FlippedData[$aid] - $FlippedData[$bid];
       }
       if ($ai === null) { return 1; }
       if ($bi === null) { return -1; }

       return $ai - $bi;
  };
  usort($data, $compare);
  echo "<pre>";print_r($data);exit;
?>

OUTPUT

Array
(
    [0] => 3470G11
    [1] => 3470G12
    [2] => 3470G13
    [3] => 3470S11
    [4] => 3470S12
    [5] => 3470S13
    [6] => 3470U11
    [7] => 3470U12
    [8] => s3470U13
    [9] => 3470E11
    [10] => 3470E12
    [11] => s3470E13
)
372

Answer

Solution:

try this instead

sort($unsorted);
$result=array();
foreach ($sortArr as $sortBy) {
foreach ($unsorted as $value) {
 if(strpos($value, $sortBy)!==false){
$result[]=$value;
}}}
print_r($result);

People are also looking for solutions to the problem: php - cURL FTP Custom Commands: Run w/o returning dir index?

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.