Сортировка части массива из другого массива

#javascript #arrays #sorting #underscore.js

#javascript #массивы #сортировка #underscore.js

Вопрос:

Мне нужно отсортировать массив на основе другого массива. Однако существует больший массив, но я хочу сортировать только по некоторым свойствам элементов. Первый массив выглядит следующим образом :

 var data = [ { id : "23", name : "Item 1", isActive : true},
  { id : "25", name : "Item 2", isActive : false},
  { id : "26", name : "Item 3", isActive : false},
  { id : "30", name : "Item 4", isActive : true},
  { id : "45", name : "Item 5", isActive : true}
]
  

Затем я делаю это, чтобы получить идентификатор активных элементов :

 var ids = _.filter(c, function(el) {
             return el.isActive === true;
          }).map(function(e) { return e.id;}) //["23","30","45"]
  

Я выполняю некоторую операцию (сравнение базы данных) и получаю, например, такой результат :

 var sorted = ["45","23","30"]
  

Поскольку я сначала отсортировал элементы по isActive, я хочу сортировать только те элементы, которые активны. (в зависимости от отсортированного массива выше) Следующим образом :

 var expected = [
  { id : "45", name : "Item 5", isActive : true},
  { id : "23", name : "Item 1", isActive : true},
  { id : "30", name : "Item 4", isActive : true},
  //try to keep order for the last values 
  { id : "25", name : "Item 2", isActive : false},
  { id : "26", name : "Item 3", isActive : false}]
  

Я попытался использовать метод _.sortBy, но это сработало не так, как ожидалось :

 var sortObj = sorted.reduce(function(acc, value, index) {
  acc[value] = value;
  return acc;
}, {});

sortedItems = _.sortBy(data, function(x) {
   return _.indexOf(sortObj, x.id)
});
  

Но это сработало не так, как ожидалось

Есть идеи? Заранее огромное спасибо =)

Комментарии:

1. Я не уверен, что понимаю, какая сортировка вам нужна

2. Вы хотите сначала весь активный элемент, затем неактивный, но сохраняющий первый порядок?

3. github.com/Teun/thenBy.js

4. да, правильно, сортировка выполняется по активным элементам. Но отсортированные элементы находятся в другом массиве

Ответ №1:

Поскольку вы хотите сохранить порядок для отсортированных и неактивных,. Мы можем использовать два связанных массива для сохранения индекса порядка, затем вы можете использовать два связанных массива для создания своего рода составного индекса.

Обновлено: надеюсь, упростить и упростить следование.

 var data = [ { id : "23", name : "Item 1", isActive : true},
  { id : "25", name : "Item 2", isActive : false},
  { id : "26", name : "Item 3", isActive : false},
  { id : "30", name : "Item 4", isActive : true},
  { id : "45", name : "Item 5", isActive : true}
];
var sorted = ["45","23","30"];

//true = active sort,  false = data sort
var order = { true: {}, false: {}};
//create order index for data
data.forEach(function (o, i) { order[false][o.id] = i; });
//create order index for sort
sorted.forEach(function (v, i) { order[true][v] = i });

data.sort(function (a, b) {
  return (b.isActive - a.isActive) || 
    order[a.isActive][a.id] - order[b.isActive][b.id];
});

console.log(data);  

Ответ №2:

Вы можете запустить 2 фильтра и объединить результат в один массив. верните el.isActive === true; и верните el.isActive === false; Вы можете отсортировать оба результата перед вставкой в конечный массив

Ответ №3:

Вы можете использовать сортировку с помощью map и object для порядка сортировки.

 var data = [{ id: "23", name: "Item 1", isActive: true }, { id: "25", name: "Item 2", isActive: false }, { id: "26", name: "Item 3", isActive: false }, { id: "30", name: "Item 4", isActive: true }, { id: "45", name: "Item 5", isActive: true }],
    sorted = ["45", "23", "30"],
    order = {};

sorted.forEach(function (a, i) { order[a] = i   1; });

// temporary array holds objects with position and sort-value
var mapped = data.map(function (el, i) {
        return { index: i, active: el.isActive, value: order[el.id] || i };
    });

// sorting the mapped array containing the reduced values
mapped.sort(function (a, b) {
    return b.active - a.active || a.value - b.value;
});

// container for the resulting order
var result = mapped.map(function (el) {
        return data[el.index];
    });

console.log(result);  
 .as-console-wrapper { max-height: 100% !important; top: 0; }  

Комментарии:

1. Это не учитывает, нет активной сортировки.. хотя он показывает 25, 26, это только случайно.

2. я вас не понимаю. что вам нужно?

3. Если вы посмотрите на его требования, он говорит .. // попробуйте сохранить порядок для последних значений, вы правильно выполняете порядок сортировки массива, но ничего не делаете, чтобы убедиться, что элементы, не входящие в отсортированный массив, хранятся в том же порядке, что и исходный массив. Надеюсь, это имеет смысл .. 🙂

4. @Keith, спасибо за разъяснения. теперь значения no active остаются в исходном порядке.

5. Хорошая Нина, я не знал о логическом вычитании. Я обновил свой ответ, чтобы включить его..