【问题标题】:Sort a PHP array by another array order and date按另一个数组顺序和日期对 PHP 数组进行排序
【发布时间】:2011-09-23 21:18:41
【问题描述】:

想知道是否有一种方法可以根据另一个数组和日期的键顺序对数组进行排序(usort 或 equiv)。我知道如何使用 usort 进行基本的日期排序,但想知道你是否可以一次性完成。

$cats = array(1,6,3,4,7,2);
$prods = array(
 array('cat'=>1,'date'=>'1/3/2011'),
 array('cat'=>2,'date'=>'1/6/2011'),
 array('cat'=>3,'date'=>'2/3/2011')
);

我希望 $prods 按 $cats 的类别顺序和 $prods 的日期顺序排序

【问题讨论】:

  • 您可能需要稍微调整一下您的数据结构,但您应该能够通过array_multisort 完成此操作
  • 我不明白你需要什么样的排序,顺便说一句,这甚至不是有效的代码
  • 我假设 id 在 arr2 中不是唯一的?
  • @MatteoRiva 哪一部分不是有效代码?我希望 $arr2 首先排序以匹配 $arr1 的顺序,然后按 $arr2 (ASC) 的日期排序。
  • @tandu 正确,如果它们是类别 ID 可能会更清楚

标签: php arrays sorting


【解决方案1】:

请注意您的低接受率,因为它会阻止人们花时间回答您的问题。请记住将有效答案标记为已接受或以其他方式向他们发表评论,解释为什么它们无效。

此解决方案在 php 5.3+ 中运行良好,如果您被困在旧版本中,您可以轻松地将 DateTime 对象替换为对 strptime 的调用。

类别未指定位置的产品被推到列表末尾(参见示例中 cat == 42 的产品)。

$cats = array(1,6,3,4,7,2);

// added a few products to test the date sorting
$prods = array(
  array('cat'=>1,'date'=>'3/3/2011'),
  array('cat'=>1,'date'=>'2/3/2011'),
  array('cat'=>1,'date'=>'1/3/2011'),
  array('cat'=>42,'date'=>'2/3/2011'),
  array('cat'=>2,'date'=>'1/3/2011'),
  array('cat'=>2,'date'=>'2/3/2011'),
  array('cat'=>2,'date'=>'1/6/2011'),
  array('cat'=>3,'date'=>'2/3/2011')
);

// need an index of category_id => position wanted in the sort
$r_cats = array_flip($cats);
// if the category of a product is not found in the requested sort, we will use 0, and product with category id 0 will be sent to the end of the sort
$r_cats[0] = count($r_cats);
// this one is needed for DateTime, put whatever your timezone is (not important for the use we do of it, but required to avoid a warning)
date_default_timezone_set('Europe/Paris');

usort($prods, function($a, $b) use($r_cats) {
  $cat_a = isset($r_cats[$a['cat']]) ? $r_cats[$a['cat']] : $r_cats[0];
  $cat_b = isset($r_cats[$b['cat']]) ? $r_cats[$b['cat']] : $r_cats[0];

  if ($cat_a < $cat_b) {
    return -1;
  } elseif ($cat_a > $cat_b) {
    return 1;
  }

  $date_a = DateTime::createFromFormat('j/n/Y', $a['date']);
  $date_b = DateTime::createFromFormat('j/n/Y', $b['date']);

  if ($date_a < $date_b) {
    return -1;
  } elseif ($date_a > $date_b) {
    return 1;
  }

  return 0;
});

var_dump($prods);

结果如下:

array(8) {
  [0]=>
  array(2) {
    ["cat"]=>
    int(1)
    ["date"]=>
    string(8) "1/3/2011"
  }
  [1]=>
  array(2) {
    ["cat"]=>
    int(1)
    ["date"]=>
    string(8) "2/3/2011"
  }
  [2]=>
  array(2) {
    ["cat"]=>
    int(1)
    ["date"]=>
    string(8) "3/3/2011"
  }
  [3]=>
  array(2) {
    ["cat"]=>
    int(3)
    ["date"]=>
    string(8) "2/3/2011"
  }
  [4]=>
  array(2) {
    ["cat"]=>
    int(2)
    ["date"]=>
    string(8) "1/3/2011"
  }
  [5]=>
  array(2) {
    ["cat"]=>
    int(2)
    ["date"]=>
    string(8) "2/3/2011"
  }
  [6]=>
  array(2) {
    ["cat"]=>
    int(2)
    ["date"]=>
    string(8) "1/6/2011"
  }
  [7]=>
  array(2) {
    ["cat"]=>
    int(42)
    ["date"]=>
    string(8) "2/3/2011"
  }
}

【讨论】:

  • 谢谢@Lepidosteus。我正在努力改进花时间回复海报的方法。我在
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 2018-11-28
  • 2011-02-10
相关资源
最近更新 更多