Сортировать массив, чтобы в нем были определенные элементы. - PullRequest
10 голосов
/ 07 августа 2011

У меня есть такой массив:

[{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}]

Я хочу получить это:

[{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}]

В принципе, я хочу, чтобы, если array[2].flag === false (или любое другое значение, которое явыберите) соответствующий элемент помещается первым в массиве, но после предыдущих соответствующих элементов.Элементы, которые не совпадают, остаются в том же порядке, в котором они были изначально.

Порядок появления важен.

Как это лучше всего сделать в JavaScript?

Ответы [ 7 ]

13 голосов
/ 31 мая 2016

Синтаксис Spread , введенный в ECMAScript6 (например, ...object), делает это относительно просто, используя метод 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 }
];

const sortedArr = arr.reduce((acc, element) => {
  if (element.flag === false) {
    return [element, ...acc];
  }
  return [...acc, element];
}, []);

Я нашел этот пример расширенной обработки параметров действительно полезным.

8 голосов
/ 07 августа 2011

Напишите пользовательскую функцию сортировки и используйте флаг для увеличения приоритета:

array.sort(function(a,b) {
  if (!a['flag'] && b['flag'])
    return 1;
  if (a['flag'] && !b['flag'])
    return -1;
  return a['other'] - b['other']
});
7 голосов
/ 07 августа 2011

Это на самом деле не сортировка.Вы можете просто выполнить цикл по массиву дважды и построить новый массив:

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]);
  }
}

Вы также можете сделать это с двумя массивами результатов и одним циклом и объединить результаты:

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);
1 голос
/ 07 августа 2011

Я думаю, это немного просто. Поскольку javascript рассматривает true как 1, а false как 0, вы можете использовать их для создания такого компаратора, как

var comp = function(a,b){
    return a.flag*1 - b.flag*1;
}

и затем вы можете использовать этот компаратор для сортировки массива

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);
0 голосов
/ 07 августа 2011

Поскольку вы хотите выбрать определенные элементы массива, но сохранить их в исходном порядке, вам нужен метод filter().Эта функция является расширением к стандартному , поэтому вам может потребоваться использовать шайбу, предоставленную на этой странице, в зависимости от того, какие браузеры вы поддерживаете.

(Когда я впервые прочитал ваш вопрос, яподумал, что вы хотите отсортировать на основе флага, а затем на основе значения, для этого вы можете использовать встроенный метод sort().)

var input = [{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}]
var false_items = input.filter(
        function(val, idx, arr) {
            return (val["flag"] == false);
        });
var true_items = input.filter(
        function(val, idx, arr) {
            return (val["flag"] == true);
        });

var sorted = false_items.concat(true_items);
0 голосов
/ 07 августа 2011
arr = arr.sort(function(a, b) { // sort the array using a custom function,
                                // which is called a number of times to
                                // determine the new order. a and b are two
                                // elements to compare. JavaScript uses the
                                // return value to determine the new order:
                                // 1  - a should come later than b
                                // -1 - a should come earlier than b
                                // 0  - they should stay in their current order
    return a.flag === true && b.flag === false
            ? 1 // if a is true and b is false a should come later on
            : a.flag === false && b.flag === true
               ? -1 // if a is false and b is true a should come earlier
               : a.other > b.other
                  ? 1 // if a.other > b.other, a must come later on
                  : a.other < b.other
                    ? -1 // if a.other < b.other, a must come earlier
                    : 0; // otherwise they are equal, so they have no order difference
});
0 голосов
/ 07 августа 2011

Метод сортировки может принимать необязательную функцию sortFunction в качестве параметра, который можно использовать для определения порядка элементов после сортировки

http://www.w3schools.com/jsref/jsref_sort.asp

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...