Сортировка массива с размерами одежды и дополнительными значениями

В настоящее время я пытаюсь сортировать некоторые массивы размеров одежды (SML XL XXL и т. Д.), Которые принадлежат массиву. Я могу сделать это с помощью следующей функции (благодаря этому месту Php Array Сортировка размеров одежды (XXS XS SML XL XXL) и чисел в динамическом массиве ):

function cmp($a, $b) { $sizes = array( "XXS" => 0, "XS" => 1, "S" => 2, "M" => 3, "L" => 4, "XL" => 5, "XXL" => 6 ); $asize = $sizes[$a]; $bsize = $sizes[$b]; if ($asize == $bsize) { return 0; } return ($asize > $bsize) ? 1 : -1; } usort($the_array, "cmp"); 

Это очень хорошо подходит для массива, который выглядит так: $ the_array («S», «M», «XL»). Однако мой массив выглядит примерно так:

 $the_array = array("S : price £10", "XXL : price £10", "M : price £10", "XS : price £10") 

Это делает его неработоспособным … Мне нужна функция, которая идеально подходит только для первой части массива до «:». Что-то подобное существует?

Спасибо за помощь.

Это решение будет искать начало каждой строки для значений размера. Он работает только до тех пор, пока размер не является префиксом другого размера, например, «X» будет префиксом «XL». Он не зависит от конкретного формата ваших данных; он найдет самое раннее появление допустимой строки размера.

 // Your comparison function: function cmp($a, $b) { // Make the array static for performance. static $sizes = array('XXS', 'XS', 'S', 'M', 'L', 'XL', 'XXL'); // Find the size of $a and $b (the first string for which strpos===0) $asize = 100; // Sort non-size strings after matching sizes. $apos = -1; $bsize = 100; $bpos = -1; foreach ($sizes AS $val => $str) { // It's important to use `===` because `==` will match on // FALSE, which is returns for no match. if (($pos = strpos($a, $str)) !== FALSE && ($apos < 0 || $pos < $apos)) { $asize = $val; $apos = $pos; } if (($pos = strpos($b, $str)) !== FALSE && ($bpos < 0 || $pos < $bpos)) { $bsize = $val; $bpos = $pos; } } return ($asize == $bsize ? 0 : ($asize > $bsize ? 1 : -1)); } usort($the_array, 'cmp'); 

Работает для любого количества X.

 function cmpSizes($a, $b) { list($a, $b) = array(strtolower($a), strtolower($b)); $weights = array('s' => 1, 'm' => 2, 'l' => 3); $primaryWeights = array(); foreach(array('a', 'b') as $var) { if(is_numeric(strpos($$var, 's'))) { $weight = $weights['s']; } elseif(is_numeric(strpos($$var, 'm'))) { $weight = $weights['m']; } elseif(is_numeric(strpos($$var, 'l'))) { $weight = $weights['l']; } else { return -1; } $primaryWeights[$var] = $weight; } if($primaryWeights['a'] === $primaryWeights['b']) { $xCt = array('a' => substr_count($a, 'x'), 'b' => substr_count($b, 'x')); if($xCt['a'] > $xCt['b']) { return $primaryWeights['a'] === $weights['s'] ? -1 : 1; } elseif($xCt['a'] < $xCt['b']) { return $primaryWeights['a'] === $weights['s'] ? 1 : -1; } return 0; } elseif ($primaryWeights['a'] > $primaryWeights['b']) { return 1; } return -1; } 

Итак, пример кода

 $userSizes = array('XS','S','XXXXS','XXL','L','M','XL'); usort($userSizes, 'cmpSizes'); var_dump($userSizes); 

Урожайность

 array(7) { [0] => string(5) "XXXXS" [1] => string(2) "XS" [2] => string(1) "S" [3] => string(1) "M" [4] => string(1) "L" [5] => string(2) "XL" [6] => string(3) "XXL" } 

Вызов usort() и использование функции explode() в своем usort() позволит вам отсортировать первую часть.

 $sizes = array( "XXS" => 0, "XS" => 1, "S" => 2, "M" => 3, "L" => 4, "XL" => 5, "XXL" => 6 ); $the_array = array("S : price £10", "XXL : price £10", "M : price £10", "XS : price £10"); // Anonymous function -- PHP 5.3+ only... // Uses the $sizes array from the higher scope... usort($the_array, function($a, $b) use ($sizes) { // Split each on space,colon,space list($asize, $aprice) = explode(' : ', $a); list($bsize, $bprice) = explode(' : ', $b); // Perform the usort comparison // which uses the sizes matched above as array keys to the $sizes array if ($sizes[$asize] == $sizes[$bsize]) { return 0; } return $sizes[$asize] < $sizes[$bsize] ? -1 : 1; }); // Output: var_dump($the_array); array(4) { [0] => string(15) "XS : price £10" [1] => string(14) "S : price £10" [2] => string(14) "M : price £10" [3] => string(16) "XXL : price £10" } 

Если разделитель не всегда является space,colon,space как указано выше и изменяется, вам нужно будет использовать preg_split() вместо explode() .

 // Split on any number of spaces surrounding the : list($asize, $aprice) = preg_split('/\s*:\s*/', $a); 

Если все, что вы пытаетесь сделать, это отсортировать массив по размерам, выполните следующие действия:

 /** THE SORT FUNCTION **/ function sortSize($data_arr) { $sizes_arr = array('XXS' => 0, 'XS' => 1, 'S' => 2, 'M' => 3, 'L' => 4, 'XL' => 5, 'XXL' => 6); $data_sort_arr = array(); foreach ($data_arr as $value) { //get the size $size_item_arr = explode(':', $value); $size_item_str = trim($size_item_arr[0]); //get the position of size from sizes array $size_pos_int = intval($sizes_arr[$size_item_str]); //populate new array with sorted data $data_sort_arr[$size_pos_int] = $value; } //sort then reset keys numerically ksort($data_sort_arr); return array_values($data_sort_arr); } /** THE SORT FUNCTION **/ /** THE TEST **/ $data_arr = array("S : price £10", "XXL : price £10", "M : price £10", "XS : price £10"); print_r(sortSize($data_arr)); /** THE TEST **/ 

Я получил следующий результат:

 Array ( [0] => XS : price £10 [1] => S : price £10 [2] => M : price £10 [3] => XXL : price £10 ) 

Надеюсь, это то, что вам нужно ?!

Приветствия.