Php 按预定义的值映射对对象数组进行排序
我有以下阵列:Php 按预定义的值映射对对象数组进行排序,php,arrays,sorting,multidimensional-array,stack,Php,Arrays,Sorting,Multidimensional Array,Stack,我有以下阵列: $inputArray = Array( [0] => stdClass Object ( [id] => 8 ) [1] => stdClass Object ( [id] => 7 ) [2] => stdClass Object ( [id] => 5 ) ) $sortingArray = [5,8,1] 我正在寻找一种通过id“值映
$inputArray = Array(
[0] => stdClass Object (
[id] => 8
)
[1] => stdClass Object (
[id] => 7
)
[2] => stdClass Object (
[id] => 5
)
)
$sortingArray = [5,8,1]
我正在寻找一种通过id“值映射”对输入数组进行排序的有效方法。。预期输出应为$inputArray,重新排序,以便第三项为第一项,第一项为第二项,以此类推
谢谢 您可以使用
array\u flip
创建临时数组。这将翻转数组,意味着值将是键
使用usort
对数组进行排序
$tempArr = array_flip( $sortingArray );
usort($inputArray, function($a, $b) use ( $tempArr ) {
$tempA = isset( $tempArr[ $a->id ] ) ? $tempArr[ $a->id ] : 999999; //If id does not exist on $sortingArray. Use 999999 as an index
$tempB = isset( $tempArr[ $b->id ] ) ? $tempArr[ $b->id ] : 999999;
return $tempA - $tempB;
});
echo "<pre>";
print_r( $inputArray );
echo "</pre>";
我在这里使用了一些东西,主要的是我使用排序数组作为
array\u replace()
的目标,并使用array\u column()
来索引对象(这需要PHP7.0+来处理对象)
array\u filter()
将删除不在输入数组中但在排序数组中的所有元素。使用array\u fill\u keys()
代替array\u flip()
,这样我就可以设置一个空值,允许过滤器工作。首先,如果输入数组是MySQL查询的结果集,那么应该通过ORDER BY子句对数据进行排序FIELD()
是一个很好的工作工具,有点奇怪,你需要反转排序逻辑并在函数后写入DESC
资源:(向下滚动至“gotcha”)
SQL Fiddle演示:
除此之外,我将提供奈杰尔和埃迪解决方案的两个精炼版本,利用php7+的优点。您选择实施哪一项与以下内容有关:
id
值的元素在进程中“生存”null
值数组,也不会删除“false”值
*我将再次声明,如果输入数组中存在重复的
id
值,则使用array\u column()
将损坏数据。tryusort()
。据我所知,usort正在比较数组中的两个值,而不是与外部值映射进行比较……或者至少我找不到一个值。你能发布你到目前为止所做的吗?到目前为止,我已经迭代了对象数组,并将每个对象与列表进行了比较。如果发现,我将插入一个新数组并从$inputArray中取消设置值,但我认为这是次优的,必须是一种更好的方法..可能的重复我认为这是一种更优雅的方法。工作起来很有魅力*我认为它是首选方法的原因是,它过滤原始输入数组中的重复项,如果键不存在,则不会失败。我不希望0
将是id
的有效值,但如果将来有人使用此方法,array\u filter()
将使用null
值销毁它们。谢谢,关于SQL,它不是很不幸……关于array\u search的重构版本,第一个响应更短、更高效……否?效率很大程度上取决于所涉及阵列的大小。如果你是指重复页面上的usort()
-array\u search()
答案,我没有对它们进行测试,但是,array\u search()
比isset()更难工作。使用isset()
的代价是只需调用array\u flip()
即可设置它array\u search()
实际遍历数组,并在找到匹配项时将其打断isset()
不能做到这一点——这就是php处理哈希映射的神奇之处。我没有资格详细解释这一点。
Array
(
[0] => stdClass Object
(
[id] => 5
)
[1] => stdClass Object
(
[id] => 8
)
[2] => stdClass Object
(
[id] => 7
)
)
$input = array_column($inputArray, null, "id");
$sort = array_fill_keys($sortingArray, null);
$output = array_filter(array_replace($sort, $input));
$array = [
(object)['id' => 8],
(object)['id' => 7],
(object)['id' => 5]
];
$order = [5, 8, 1]; // custom sort order
$order = array_flip($order); // restructure for easy lookup with isset()
$order[''] = max(array_column($array, 'id')) + 1; // append value higher than max for outlying ids
usort($array, function($a, $b) use ($order) {
return ($order[$a->id] ?? $order['']) <=> ($order[$b->id] ?? $order['']);
});
var_export($array);
$array = [
(object)['id' => 8],
(object)['id' => 7],
(object)['id' => 5]
];
$order = [5, 8, 1];
$order = array_flip($order); // flip for future key comparisons
$keyed = array_column($array, null, 'id'); // declare id values as new keys
$filtered_order = array_intersect_key($order, $keyed); // remove unwanted order keys
$replaced = array_replace($filtered_order, $keyed); // apply objects to output array
var_export(array_values($replaced)); // re-index the output (if desired)