简体   繁体   English

PHP 按多个值排序数组:正/负然后是第二个值

[英]PHP Sort Array by multiple values : positive/negative then second value

I am stuck on a PHP concept that seems simple to me at first:我被困在 PHP 概念上,起初对我来说似乎很简单:

I have this array:我有这个数组:

$test = array(
    array(
        'quantity' => 0,
        'nbr_sales' => 10
    ),
    array(
        'quantity' => 10,
        'nbr_sales' => 100
    ),
    array(
        'quantity' => 10,
        'nbr_sales' => 1250
    ),
    array(
        'quantity' => 20,
        'nbr_sales' => 5000
    ),
    array(
        'quantity' => -1,
        'nbr_sales' => 990
    ),
    array(
        'quantity' => 0,
        'nbr_sales' => 1000
    )
);

I want to sort this multidimensional array by checking if quantity is positive or negative, then by nbr_sales (DESC), so a result like this:我想通过检查quantity是正数还是负数,然后通过nbr_sales (DESC) 对这个多维数组进行排序,所以结果如下:

$result = array(
    array(
        'quantity' => 20,
        'nbr_sales' => 5000
    ),
    array(
        'quantity' => 10,
        'nbr_sales' => 1250
    ),
    array(
        'quantity' => 10,
        'nbr_sales' => 100
    ),
    array(
        'quantity' => 0,
        'nbr_sales' => 1000
    ),
    array(
        'quantity' => 0,
        'nbr_sales' => 10
    ),
    array(
        'quantity' => -1,
        'nbr_sales' => 990
    )
);

I tried several approaches but nothing really conclusive:我尝试了几种方法,但没有任何结论:

$result = array();
$positives = array(); $negatives = array();
foreach($test as $t) {
    $t['quantity'] > 0 ? array_push($positives, $t) : array_push($negatives, $t);
}
usort($positives, function($a, $b){
    return $a['nbr_sales'] == $b['nbr_sales'] ? 0 : ($a['nbr_sales'] < $b['nbr_sales'] ? 1 : -1);
});
usort($negatives, function($a, $b){
    return $a['nbr_sales'] == $b['nbr_sales'] ? 0 : ($a['nbr_sales'] < $b['nbr_sales'] ? 1 : -1);
});
array_push($result, $positives);
array_push($result, $negatives);

var_dump($result)

array(2) {
  [0] => array(3) {
    [0] => array(2) {
      ["quantity"] => int(20)
      ["nbr_sales"]=> int(5000)
    }
    [1]=> array(2) {
      ["quantity"] => int(10)
      ["nbr_sales"]=> int(1250)
    }
    [2] => array(2) {
      ["quantity"] => int(10)
      ["nbr_sales"]=> int(100)
    }
  }
  [1]=> array(3) {
    [0] => array(2) {
      ["quantity"] => int(0)
      ["nbr_sales"]=> int(1000)
    }
    [1]=> array(2) {
      ["quantity"]=> int(-1)
      ["nbr_sales"] => int(990)
    }
    /* should be above */
    [2]=> array(2) {
      ["quantity"] => int(0)
      ["nbr_sales"] => int(10)
    }
  }
}

Thanks for your help:)谢谢你的帮助:)

You want to sort in two steps.您想分两步进行排序。 So use a callback to do exactly that:所以使用回调来做到这一点:

<?php
$data = [
  [
    'quantity' => 0,
    'nbr_sales' => 10
  ], [
    'quantity' => 10,
    'nbr_sales' => 100
  ], [
    'quantity' => 10,
    'nbr_sales' => 1250
  ], [
    'quantity' => 20,
    'nbr_sales' => 5000
  ], [
    'quantity' => -1,
    'nbr_sales' => 990
  ], [
    'quantity' => 0,
    'nbr_sales' => 1000
  ]
];

usort($data, function($a, $b) {
  $q = $b['quantity'] <=> $a['quantity'];
  if ($q != 0) return $q;
  return $b['nbr_sales'] <=> $a['nbr_sales'];
});

print_r($data);

If you prefer a trinary notation that would be the equivalent:如果您更喜欢等效的三进制表示法:

usort($data, function($a, $b) {
  return 
    0 == $b['quantity'] - $a['quantity']
      ? $b['nbr_sales'] <=> $a['nbr_sales'] 
      : $b['quantity'] <=> $a['quantity'];
});

The output obviously is: output 显然是:

Array
(
    [0] => Array
        (
            [quantity] => 20
            [nbr_sales] => 5000
        )
    [1] => Array
        (
            [quantity] => 10
            [nbr_sales] => 1250
        )
    [2] => Array
        (
            [quantity] => 10
            [nbr_sales] => 100
        )
    [3] => Array
        (
            [quantity] => 0
            [nbr_sales] => 1000
        )
    [4] => Array
        (
            [quantity] => 0
            [nbr_sales] => 10
        )
    [5] => Array
        (
            [quantity] => -1
            [nbr_sales] => 990
        )
)

Visually, it's not the result I'm searching for.从视觉上看,这不是我要寻找的结果。 For example if I change例如,如果我改变

$data = [
    [
        'quantity' => 0,
        'nbr_sales' => 10
    ], [
        'quantity' => 10000, // change here
        'nbr_sales' => 100
    ], [
        'quantity' => 10,
        'nbr_sales' => 1250
    ], [
        'quantity' => 20,
        'nbr_sales' => 5000
    ], [
        'quantity' => -1,
        'nbr_sales' => 990
    ], [
        'quantity' => 0,
        'nbr_sales' => 1000
    ]
];

usort($data, function($a, $b) {
    $q = $b['quantity'] - $a['quantity'];
    if ($q != 0) return $q;
    return $b['nbr_sales'] - $a['nbr_sales'];
});

I get this:我明白了:

array(6) {
  [0]=> array(2) {
    ["quantity"]=> int(10000)
    ["nbr_sales"]=> int(100)
  }
  [1]=> array(2) {
    ["quantity"]=> int(20)
    ["nbr_sales"]=> int(5000)
  }
  [2]=> array(2) {
    ["quantity"]=> int(10)
    ["nbr_sales"]=> int(1250)
  }
  [3]=> array(2) {
    ["quantity"]=> int(0)
    ["nbr_sales"]=> int(1000)
  }
  [4]=> array(2) {
    ["quantity"]=> int(0)
    ["nbr_sales"]=> int(10)
  }
  [5]=> array(2) {
    ["quantity"]=> int(-1)
    ["nbr_sales"]=> int(990)
  }
}

But I'm looking for this:但我正在寻找这个:

array(6) {
  [0]=> array(2) {
    ["quantity"]=> int(20)
    ["nbr_sales"]=> int(5000)
  }
  [1]=> array(2) {
    ["quantity"]=> int(10)
    ["nbr_sales"]=> int(1250)
  }
  [2]=> array(2) {
    ["quantity"]=> int(10000)
    ["nbr_sales"]=> int(100)
  }
  [3]=> array(2) {
    ["quantity"]=> int(0)
    ["nbr_sales"]=> int(1000)
  }
  [4]=> array(2) {
    ["quantity"]=> int(0)
    ["nbr_sales"]=> int(10)
  }
  [5]=> array(2) {
    ["quantity"]=> int(-1)
    ["nbr_sales"]=> int(990)
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM