对数组进行排序以在数组中首先包含特定项

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)

  • reduce方法是否不缺少第二个参数(initialValue)?,在这种情况下为空数组。难道不是吗?```arr.reduce((acc,element)=> {},[])`'' (2认同)
  • 这是一种非常昂贵的方法。`const rebuiltArray = [...acc.filter(elem => elem.flag), ...acc.filter(elem => !elem.flag)]` ([有关更多详细信息,请参阅此答案](https:// /stackoverflow.com/a/62071369/5125537)) 更容易阅读,并且根据我的测量,**事实证明比你的方法快 20 倍**。 (2认同)

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)

在我看来,它比使用comparerreducer函数更容易让人类阅读,并且(基于测量)它也是一个性能非常好的解决方案。


性能对比:

我看到的最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)


Rob*_*rne 9

编写自定义排序函数并使用该标志来增加优先级:

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)


Guf*_*ffa 7

这实际上并不是排序.您可以遍历数组两次并构建一个新数组:

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)


tir*_*ran 6

我觉得这有点简单。因为 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)