按照自定义顺序排列一个php数组
我有一个数组的数组:
Array ( [0] => Array ( [id] = 7867867, [title] = 'Some Title'), [1] => Array ( [id] = 3452342, [title] = 'Some Title'), [2] => Array ( [id] = 1231233, [title] = 'Some Title'), [3] => Array ( [id] = 5867867, [title] = 'Some Title') )
需要按照特定的顺序进行:
- 3452342
- 5867867
- 7867867
- 1231233
我将如何去做呢? 我之前已经对数组进行了sorting,并且阅读了大量关于它的其他文章,但它们总是基于比较(即valueA <valueB)。
帮助表示赞赏。
您可以使用usort()
来精确地指定数组如何sorting。 在这种情况下, $order
数组可以在比较函数中使用。
下面的例子使用closure
来简化生活。
$order = array(3452342, 5867867, 7867867, 1231233); $array = array( array('id' => 7867867, 'title' => 'Some Title'), array('id' => 3452342, 'title' => 'Some Title'), array('id' => 1231233, 'title' => 'Some Title'), array('id' => 5867867, 'title' => 'Some Title'), ); usort($array, function ($a, $b) use ($order) { $pos_a = array_search($a['id'], $order); $pos_b = array_search($b['id'], $order); return $pos_a - $pos_b; }); var_dump($array);
这个工作的关键在于正在比较的值,是$order
数组中的id
的位置。
比较函数通过查找$order
数组内的两个项目的id的位置来工作。 如果在$order
数组中, $a['id']
出现在$b['id']
之前,那么函数的返回值是负数( $a
越小越好)。 如果$a['id']
在$b['id']
之后,那么函数返回一个正数( $a
越大,“汇”下来)。
最后,没有特别的理由使用封闭; 这只是我快速写出这些一次性function的方法。 它可以同样使用正常的命名函数。
扩展萨拉思的这个额外的要求的答案 :
现在,当我将项目添加到数组而不是sorting? 我不在乎他们出现的顺序是什么,只要是我指定的顺序。
您需要在sortingfunction中添加两个附加条件:
- “不关心”项目必须被认为大于“关心”项目
- 两个“不在乎”的项目必须被认为是平等的
所以修改后的代码是:
$order = array( 3452342, 5867867, 7867867, 1231233 ); $array = array( array("id" => 7867867, "title" => "Must Be #3"), array("id" => 3452342, "title" => "Must Be #1"), array("id" => 1231233, "title" => "Must Be #4"), array("id" => 5867867, "title" => "Must Be #2"), array("id" => 1111111, "title" => "Dont Care #1"), array("id" => 2222222, "title" => "Dont Care #2"), array("id" => 3333333, "title" => "Dont Care #3"), array("id" => 4444444, "title" => "Dont Care #4") ); function custom_compare($a, $b){ global $order; $a = array_search($a["id"], $order); $b = array_search($b["id"], $order); if($a === false && $b === false) { // both items are dont cares return 0; // a == b } else if ($a === false) { // $a is a dont care item return 1; // $a > $b } else if ($b === false) { // $b is a dont care item return -1; // $a < $b } else { return $a - $b; } } shuffle($array); // for testing var_dump($array); // before usort($array, "custom_compare"); var_dump($array); // after
输出:
Before | After -------------------------------+------------------------------- array(8) { | array(8) { [0]=> | [0]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(4444444) | int(3452342) ["title"]=> | ["title"]=> string(12) "Dont Care #4" | string(10) "Must Be #1" } | } [1]=> | [1]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(3333333) | int(5867867) ["title"]=> | ["title"]=> string(12) "Dont Care #3" | string(10) "Must Be #2" } | } [2]=> | [2]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(1231233) | int(7867867) ["title"]=> | ["title"]=> string(10) "Must Be #4" | string(10) "Must Be #3" } | } [3]=> | [3]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(1111111) | int(1231233) ["title"]=> | ["title"]=> string(12) "Dont Care #1" | string(10) "Must Be #4" } | } [4]=> | [4]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(5867867) | int(2222222) ["title"]=> | ["title"]=> string(10) "Must Be #2" | string(12) "Dont Care #2" } | } [5]=> | [5]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(2222222) | int(1111111) ["title"]=> | ["title"]=> string(12) "Dont Care #2" | string(12) "Dont Care #1" } | } [6]=> | [6]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(3452342) | int(3333333) ["title"]=> | ["title"]=> string(10) "Must Be #1" | string(12) "Dont Care #3" } | } [7]=> | [7]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(7867867) | int(4444444) ["title"]=> | ["title"]=> string(10) "Must Be #3" | string(12) "Dont Care #4" } | } } | }
您需要定义自己的比较函数,如果要维护索引关联,请使用usort
或uasort
。
这是我如何解决在ASC顺序multidimensional arraysorting问题,希望它会有所帮助
$arrayFilter = array( array( 'product_tag' => 'xenia', 'id' => 4 ), array ( 'product_tag' => 'worn', 'id' => 5 ), array ( 'product_tag' => 'woven', 'id' => 3 ), array ( 'product_tag' => 'nude', 'id' => 1 )); for ($i = 0; $i < sizeof($arrayFilter); $i++) { for ($j=$i+1;$j <sizeof($arrayFilter); $j++) { if ($arrayFilter[$i]['id'] > $arrayFilter[$j]['id']) { $c = $arrayFilter[$i]; $arrayFilter[$i] = $arrayFilter[$j]; $arrayFilter[$j] = $c; } } } print_r($arrayFilter);
OUTPUT:
Array ( [0] => Array ( [product_tag] => nude [id] => 1 ) [1] => Array ( [product_tag] => woven [id] => 3 ) [2] => Array ( [product_tag] => xenia [id] => 4 ) [3] => Array ( [product_tag] => worn [id] => 5 ) )
@salathe对于那些很难理解salathe的使命的人,
$ array中的每个项目都是比赛中的“冠军”,在新arrays的开始处(除了他们希望成为0号的号码之外)。
$ a是主场冠军,$ b是对手的冠军。
callback中的$ pos_a和$ pos_b是什么属性将用于争夺冠军a和b。 在这种情况下,这个属性是$ order中冠军id的索引。
然后是在返回的战斗。 现在我们来看看是否有更多或更less的属性更好。 在一次未成年的战斗中,主场冠军希望得到一个负数,这样他可以更快地进入阵容。 客场冠军想要一个正数。 如果有一个0,这是一个领带。
因此,当客场冠军属性(以$秩序的索引)从主队属性中减去时,按照这种类比,客场冠军属性越大,获得正数越less。 但是如果你想扭转属性的使用方式,那么现在主场冠军的属性会从客场冠军中减去。 在这种情况下,客场比赛的数量越大,他的比赛结束数就越多。
代码看起来像:
注意:代码运行很多次,就像一个真正的比赛有很多的战斗,以决定谁先获得(即0 /数组的开始)
//tournament with goal to be first in array usort($champions, function ($home, $away) use ($order) { $home_attribute = array_search($a['id'], $order); $away_attribute = array_search($b['id'], $order); //fight with desired outcome for home being negative and away desiring positive return $home_attribute - $away_attribute; });