Сортировка массива, чтобы сначала в массиве были определенные элементы
у меня есть массив так:
[{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 в качестве параметра, который можно использовать для определения порядка элементов после сортировки
поскольку вы хотите выбрать определенные элементы массива, но сохранить их в исходном порядке, вы хотите 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
});