通过预定义的值映射对对象数组进行排序

时间:2018-10-09 05:52:47

标签: 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重新排序,以便第3个项目位于第一个,第一个项目为第2个,依此类推。

谢谢!

3 个答案:

答案 0 :(得分:2)

您可以使用webpackHotDevClient.js:138 C:/Users/benja/Documents/Udacity/Project-7/react-map/node_modules/object-assign/index.js There are multiple modules with names that only differ in casing. This can lead to unexpected behavior when compiling on a filesystem with other case-semantic. Use equal casing. Compare these module identifiers: * C:\Users\benja\Documents\Udacity\Project-7\react-map\node_modules\object-assign\index.js Used by 1 module(s), i. e. C:\Users\benja\Documents\Udacity\Project-7\react-map\node_modules\react-scripts\config\polyfills.js * C:\Users\benja\documents\udacity\project-7\react-map\node_modules\object-assign\index.js Used by 3 module(s), i. e. C:\Users\benja\documents\udacity\project-7\react-map\node_modules\react\cjs\react.development.js printWarnings @ webpackHotDevClient.js:138 handleWarnings @ webpackHotDevClient.js:155 ./node_modules/react-dev-utils/webpackHotDevClient.js.connection.onmessage @ webpackHotDevClient.js:208 ./node_modules/sockjs-client/lib/event/eventtarget.js.EventTarget.dispatchEvent @ eventtarget.js:51 (anonymous) @ main.js:278 ./node_modules/sockjs-client/lib/main.js.SockJS._transportMessage @ main.js:276 ./node_modules/sockjs-client/lib/event/emitter.js.EventEmitter.emit @ emitter.js:50 WebSocketTransport.ws.onmessage @ websocket.js:35 webpackHotDevClient.js:138 (webpack)/buildin/global.js There are multiple modules with names that only differ in casing. This can lead to unexpected behavior when compiling on a filesystem with other case-semantic. Use equal casing. Compare these module identifiers: * C:\Users\benja\Documents\Udacity\Project-7\react-map\node_modules\webpack\buildin\global.js Used by 23 module(s), i. e. C:\Users\benja\Documents\Udacity\Project-7\react-map\node_modules\sockjs-client\lib\entry.js * C:\Users\benja\documents\udacity\project-7\react-map\node_modules\webpack\buildin\global.js Used by 2 module(s), i. e. C:\Users\benja\documents\udacity\project-7\react-map\node_modules\symbol-observable\es\index.js printWarnings @ webpackHotDevClient.js:138 handleWarnings @ webpackHotDevClient.js:155 ./node_modules/react-dev-utils/webpackHotDevClient.js.connection.onmessage @ webpackHotDevClient.js:208 ./node_modules/sockjs-client/lib/event/eventtarget.js.EventTarget.dispatchEvent @ eventtarget.js:51 (anonymous) @ main.js:278 ./node_modules/sockjs-client/lib/main.js.SockJS._transportMessage @ main.js:276 ./node_modules/sockjs-client/lib/event/emitter.js.EventEmitter.emit @ emitter.js:50 WebSocketTransport.ws.onmessage @ websocket.js:35 webpackHotDevClient.js:138 (webpack)/buildin/module.js There are multiple modules with names that only differ in casing. This can lead to unexpected behavior when compiling on a filesystem with other case-semantic. Use equal casing. Compare these module identifiers: * C:\Users\benja\Documents\Udacity\Project-7\react-map\node_modules\webpack\buildin\module.js Used by 3 module(s), i. e. C:\Users\benja\Documents\Udacity\Project-7\react-map\node_modules\node-libs-browser\node_modules\punycode\punycode.js * C:\Users\benja\documents\udacity\project-7\react-map\node_modules\webpack\buildin\module.js Used by 2 module(s), i. e. C:\Users\benja\documents\udacity\project-7\react-map\node_modules\lodash\isBuffer.js来创建一个临时数组。这将翻转数组,这意味着值将是关键。

使用array_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>";

答案 1 :(得分:1)

我在这里使用了几件事,主要是我将排序数组用作array_replace()的目标,并使用array_column()来索引对象(这需要PHP 7.0 +用于处理对象)...

$input = array_column($inputArray, null, "id");   
$sort = array_fill_keys($sortingArray, null);
$output = array_filter(array_replace($sort, $input));

array_filter()将删除不在输入数组中但在排序数组中的所有元素。使用array_fill_keys()代替array_flip(),以便我可以设置一个空值,使过滤器可以工作。

答案 2 :(得分:0)

首先,如果输入数组是MySQL查询的结果集,则应该通过ORDER BY子句对数据进行排序。 FIELD()是一项出色的工作工具,有些奇怪,您需要颠倒排序逻辑并在函数后写上DESC

资源:https://www.electrictoolbox.com/mysql-order-specific-field-values/(向下滚动到“陷阱”)

SQL Fiddle演示:http://sqlfiddle.com/#!9/6b996f/1


除此之外,我还将利用php7 +优点提供Nigel和Eddie解决方案的两个改进版本。您选择实施哪一个将与:

  1. 是否要允许具有重复id值的元素“生存”该过程
  2. 哪一个对于您的 actual 项目数据(输入数组和自定义订单数组的大小)的执行效率更高
  3. 个人喜好(两个摘要都可以用3到5行写成,因此简洁程度不是一个标准)

解决方案1:usort()null coalescing operator

PHP Demo

$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);

*请注意,我可以将$outlier作为第二个use参数传递到自定义函数范围中,并用$order['']替换所有$outlier变量,但是我选择了将异常数据添加到查找数组中。

*我在自定义函数中使用了括号,不仅是为了提高可读性,而且是为了确保按预期执行评估-在没有括号分组的情况下,我实际上没有费心检查评估是否相同。

解决方案2:array_replace()具有键控数组的翻转和过滤后的排序数组

PHP Demo

$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)

*请注意,这不会生成null值的超大数组,也不会删除“假”值。

*我将再次声明,如果在输入数组中存在重复的array_column()值,则使用id会损坏数据。