DLe*_*rdi 11 javascript arrays sorting
我有一个这样的阵列:
[{flag: true, other: 1},
{flag: true, other: 2},
{flag: false, other: 3},
{flag: true, other: 4},
{flag: true, other: 5},
{flag: true, other: 6},
{flag: false, other: 7}]
Run Code Online (Sandbox Code Playgroud)
我想要这个:
[{flag: false, other: 3},
{flag: false, other: 7},
{flag: true, other: 1},
{flag: true, other: 2},
{flag: true, other: 4},
{flag: true, other: 5},
{flag: true, other: 6}]
Run Code Online (Sandbox Code Playgroud)
基本上我想要if array[2].flag === false(或我选择的任何其他值)匹配元素首先放在数组中,但是在之前的匹配元素之后.不匹配的元素保持原来的顺序.
外观顺序很重要.
如何在JavaScript中做到最好?
fel*_*rez 15
ES6在一个...object操作中使这个相对简单:
const arr = [
{ flag: true, other: 1 },
{ flag: true, other: 2 },
{ flag: false, other: 3 },
{ flag: true, other: 4 },
{ flag: true, other: 5 },
{ flag: true, other: 6 },
{ flag: false, other: 7 }
];
const sortedArr = arr.reduce((acc, element) => {
if (element.flag === false) {
return [element, ...acc];
}
return [...acc, element];
}, []);
Run Code Online (Sandbox Code Playgroud)
Bir*_*rbi 11
一种更简单、更优雅的方法是通过两次过滤旧数组来构建一个新数组:一次过滤flag: true和一次过滤flag: false。总之它看起来像:
// THE INITIAL ARRAY:
const originalArray = [
{flag: true, other: 1},
{flag: true, other: 2},
{flag: false, other: 3},
{flag: true, other: 4},
{flag: true, other: 5},
{flag: true, other: 6},
{flag: false, other: 7}
];
// THE SORTED ARRAY:
const sortedArray = [
...originalArray.filter(({flag}) => flag),
...originalArray.filter(({flag}) => !flag)
];
Run Code Online (Sandbox Code Playgroud)
在我看来,它比使用comparer或reducer函数更容易让人类阅读,并且(基于测量)它也是一个性能非常好的解决方案。
我看到的最upvoted答案使用arr.reduce()周围进行20倍比这个解决方案慢。我是用ES6 Console做对比的,大家也可以自己测试一下!
array.reduce()方式:const arr = [
{ flag: true, other: 1 },
{ flag: true, other: 2 },
{ flag: false, other: 3 },
{ flag: true, other: 4 },
{ flag: true, other: 5 },
{ flag: true, other: 6 },
{ flag: false, other: 7 }
];
// Lets multiple the array items 11 times to increase the looping process:
new Array(11).fill().forEach(x => arr.push(...arr));
console.time();
const reducedArr = arr.reduce((acc, element) => {
if (element.flag === false) {
return [element, ...acc];
}
return [...acc, element];
}, []);
console.timeEnd(); // RESULTS: between 285-350ms
Run Code Online (Sandbox Code Playgroud)
array.filter()方式:const arr = [
{ flag: true, other: 1 },
{ flag: true, other: 2 },
{ flag: false, other: 3 },
{ flag: true, other: 4 },
{ flag: true, other: 5 },
{ flag: true, other: 6 },
{ flag: false, other: 7 }
];
// Lets multiple the array items 11 times to increase the looping process:
new Array(11).fill().forEach(x => arr.push(...arr));
console.time();
const rebuiltArray = [
...arr.filter(x => !!x.flag),
...arr.filter(x => !x.flag)
];
console.timeEnd(); // RESULTS: between 6-20ms
Run Code Online (Sandbox Code Playgroud)
编写自定义排序函数并使用该标志来增加优先级:
array.sort(function(a,b) {
if (!a['flag'] && b['flag'])
return 1;
if (a['flag'] && !b['flag'])
return -1;
return a['other'] - b['other']
});
Run Code Online (Sandbox Code Playgroud)
这实际上并不是排序.您可以遍历数组两次并构建一个新数组:
var result = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i].flag === false) {
result.push(arr[i]);
}
}
for (var i = 0; i < arr.length; i++) {
if (!arr[i].flag === false) {
result.push(arr[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
您也可以使用两个结果数组和一个循环,并连接结果:
var result1 = [], result2 = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i].flag === false) {
result1.push(arr[i]);
} else {
result2.push(arr[i]);
}
}
var result = result1.concat(result2);
Run Code Online (Sandbox Code Playgroud)
我觉得这有点简单。因为 javascript 将 true 视为 1,将 false 视为 0,所以您可以使用它们来创建这样的比较器,
var comp = function(a,b){
return a.flag*1 - b.flag*1;
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用这个比较器对数组进行排序
var arr = [{flag: true, other: 1},
{flag: true, other: 2},
{flag: false, other: 3},
{flag: true, other: 4},
{flag: true, other: 5},
{flag: true, other: 6},
{flag: false, other: 7}];
arr.sort(comp);
Run Code Online (Sandbox Code Playgroud)