Сортировка массива, чтобы сначала в массиве были определенные элементы

у меня есть массив так:

[{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 ответов


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

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

ES6 делает это относительно простым в пределах 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];
}, []);

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

array.sort(function(a,b) {
  if (!a['flag'] && b['flag'])
    return 1;
  if (a['flag'] && !b['flag'])
    return -1;
  return a['other'] - b['other']
});

Я думаю, что это слишком просто. Поскольку 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);

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

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


поскольку вы хотите выбрать определенные элементы массива, но сохранить их в исходном порядке, вы хотите 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);

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