我目前正在尝试对属于数组的一些服装尺寸数组(S M L XL XXL 等)进行排序。我可以通过以下函数来做到这一点(感谢这个地方Php Array Sorting Clothing Sizes (XXS XS S M L XL XXL) and Numbers on a Dynamic Array):
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 = [
"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()
将允许您对第一部分进行排序。
$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
)
我希望这就是您所需要的?!
干杯。