簡體   English   中英

對多維產品數組進行排序的邏輯

[英]logic to sort the multidimensional product array

我必須根據價格或大小對多維數組進行排序,但問題是,它有一個問題,它排序的第一個數組總是錯誤的,我嘗試使用 usort 等,但它們都給出相同的結果,我們有需要根據價格或尺寸分類的產品列表。 我找到了很多答案,但問題仍然存在。 產品應根據價格排序,即從低到高或尺寸將按寬度排序,例如產品尺寸 120 x 60,因此 120 是寬度,它應該是最后一個產品

Function 對多維數組進行排序

function array_sort($array, $on, $order=SORT_ASC){
   $new_array = array();
   $sortable_array = array();
   if (count($array) > 0) {
      foreach ($array as $k => $v) {
         if (is_array($v)) {
            foreach ($v as $k2 => $v2) {
                if ($k2 == $on) {
                    $sortable_array[$k] = $v2;
                }
            }
        } else {
            $sortable_array[$k] = $v;
        }
    }

    switch ($order) {
        case SORT_ASC:
            asort($sortable_array);
            break;
        case SORT_DESC:
            arsort($sortable_array);
            break;
    }

    foreach ($sortable_array as $k => $v) {
        $new_array[$k] = $array[$k];
    }
 }
 return $new_array; }

這是我要排序的數組

$sortingArray = Array(
    '0' => Array(
       'id' => 1287,
       'data-price' => '£209.95',
       'size' => '120 x 60'
    ),
    '1' => Array(
       'id' => 1263,
       'data-price'=> '£14.95',
       'size' => '18 x 13'
     ),

    '2' => Array(
       'id' => 1264,
       'data-price' => '£15.95',
       'size' => '20 x 15'
    ),

   '3' => Array(
      'id' => 1245,
      'data-price' => '£29.95',
      'size' => '30 x 20'
   ),

   '4' => Array
       (
        'id' => 1315,
        'data-price' => '£39.95',
        'size' => '50 x 13'
      ),
    '5' => Array(
        'id' => 1275,
        'data-price' => '£94.95',
        'size' => '60 x 40'
    ),
   '6' => Array
      (
        'id' => 1281,
        'data-price' => '£119.95',
        'size' => '75 x 50'
      ),

   );

到 Output 結果

$rectangleProductDetails = array_sort($sortingArray, 'size', SORT_ASC);
print_r($rectangleProductDetails);

建議的解決方案:

function array_sort(array $array, string $on, string $order = 'ASC') {
    $sortableArray = $array;
    switch ($on) {
        case 'size':
            usort($sortableArray, 'sortBySize');
            break;
        case 'price':
            usort($sortableArray, 'sortByPrice');
            break;
        default:
            return $array;
            break;
    }

    if (strtoupper($order) === 'DESC') {
        return array_reverse($sortableArray);
    }

    return $sortableArray;
}

function sortByPrice(array $a, array $b) {
    return (float) mb_substr($a['data-price'], 1) <=> (float) mb_substr($b['data-price'], 1);
}

function sortBySize(array $a, array $b) {
    return (int) $a['size'] <=> (int) $b['size'];
}

這個怎么運作:

  • 它切換排序標准並選擇正確的排序回調(從單獨定義的函數中)與usort一起使用。 如果提供了不受支持的值,它將返回原始訂單。
  • 數組始終按升序排序(即使提供了一些虛假值作為順序)。 如果定義了降序,我們使用array_reverse以相反的順序返回排序后的數組。
  • 由於您已指定僅應使用寬度來排序大小,因此通過將大小值轉換為 integer 對其進行排序(因為 integer 值僅考慮到第一個非數字字符的數字)。
  • 按價格排序需要提取金額,這是通過mb_substr($priceVariable, 1)完成的(它消除了第一個字符)。 請注意, substr在這里不起作用,因為井號是一個多字節字符,因此必須使用 substring function 的多字節版本。
  • 這兩個排序功能都使用了spaceship 運算符

最后,請注意$on排序標准與數組鍵不完全匹配(我使用'price'而不是'data-price' ;它們可以匹配 - 就像'size'一樣 - 但不是必須的)。 這樣做的好處是,如果數組中的索引發生更改,您只需要修改排序回調,而不必在調用自定義array_sort function 的每個地方都進行修改。

您需要將 size 轉換為 int

也許像

usort($sortingArray, function($a, $b) {
    //you can calculate your size and sort the result
    //or split it into 2 number and then sort it
    return intval($a["size"]) < intval($b["size"]) ? -1 : 1;
});

閱讀您要實現的目標,我認為以下是實現解決方案的正確方法。

由於您需要幾種不同的方法來根據其字段的值對數組進行排序,並根據他們自己的需要,我認為一種策略模式將適合這種情況。

為此,我定義了幾個函數,一個是清理包含價格的字符串,然后使用太空船運算符進行比較。

對於大小,我們只需獲取寬度並比較整數。

最后,默認值只會應用常規比較。

function priceSort($on)
{
    return function ($item, $other) use ($on) {
        $itemPrice = filter_var($item[$on], FILTER_SANITIZE_NUMBER_FLOAT);
        $otherPrice = filter_var($other[$on], FILTER_SANITIZE_NUMBER_FLOAT);

        return floatval($itemPrice) <=> floatval($otherPrice);
    };
}

function widthSort($on)
{
    return function ($item, $other) use ($on) {
        $itemWidth = explode('x', str_replace(' ', '', $item[$on]))[0];
        $otherWidth = explode('x', str_replace(' ', '', $other[$on]))[0];

        return intval($itemWidth) <=> intval($otherWidth);
    };
}

function defaultSort($on)
{
    return function ($item, $other) use ($on) {
        return $item[$on] <=> $other[$on];
    };
}

function determineSortStrategy($on)
{
    switch ($on) {
        case 'size':
            $strategy = widthSort($on);
            break;
        case 'data-price':
            $strategy = priceSort($on);
            break;
        default:
            $strategy = defaultSort($on);
            break;
    }

    return $strategy;
}

function orderBased($strategy, $order)
{
    if ($order === SORT_DESC) {
        $strategy = function ($item, $other) use ($strategy) {
            return -1 * $strategy($item, $other);
        };
    }

    return $strategy;
}

function array_sort($array, $on = 'id', $order = SORT_ASC)
{
    $strategy = determineSortStrategy($on);
    $strategy = orderBased($strategy, $order);

    usort($array, $strategy);

    return $array;
}

$result = array_sort($sortingArray, 'data-price', SORT_DESC);

echo '<pre>';
print_r($result);
echo '</pre>';

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM