使用服装尺寸和额外值对数组进行排序

时间:2012-11-01 12:49:09

标签: php arrays

我目前正在尝试对属于阵列的一些服装尺寸阵列(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 = array("S : price £10", "XXL : price £10", "M : price £10", "XS : price £10")

这使得它不起作用......我需要一个理想情况下只查看数组的第一部分到“:”的函数。有这样的事吗?

感谢您的帮助。

4 个答案:

答案 0 :(得分:2)

此解决方案将在每个字符串的开头搜索大小值。它只有在没有大小是另一个大小的前缀时才有效,例如'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');

答案 1 :(得分:1)

适用于任何数量的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"
}

答案 2 :(得分:0)

调用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);

答案 3 :(得分:0)

如果您要做的就是按大小对数组进行排序,则可以执行以下操作:

/** 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
)

我希望这就是你需要的东西?!

干杯。