Как объединить и упорядочить 2 массива по определенному идентификатору - PullRequest
0 голосов
/ 09 октября 2018

Я хочу объединить эти 2 массива по ID и отсортировать объединенный массив результатов по ID desc.

  • Не хочу использовать какую-либо внешнюю библиотеку, такую ​​как Lodash или Underscore

  • Предпочитают использовать ES6 с меньшим количеством возможных строк кода

.

const array1 = [
  {id: "14",  text: "Notice 14"},
  {id: "13",  text: "Notice 13"},
  {id: "12",  text: "Notice 12"},
  {id: "11",  text: "Notice 11"},
  {id: "10",  text: "Notice 10"},
]

const array2 = [ 
  {id: "11",  text: "Notice 11a"},
  {id: "14",  text: "Notice 14a"},
  {id: "12",  text: "Notice 12"},
  {id: "15",  text: "Notice 15"},
]

Iхотите объединенный массив по идентификатору и порядок по идентификатору desc:

[
{id: "15",  text: "Notice 15"}
{id: "14",  text: "Notice 14a"}
{id: "13",  text: "Notice 13"}
{id: "12",  text: "Notice 12"}
{id: "11",  text: "Notice 11a"}
{id: "10",  text: "Notice 10"}
]

Ответы [ 4 ]

0 голосов
/ 09 октября 2018

Используя современный Javascript, вы можете использовать объект Map для решения этой проблемы.

const array1 = [
    {id: "14",  text: "Notice 14"},
    {id: "13",  text: "Notice 13"},
    {id: "12",  text: "Notice 12"},
    {id: "11",  text: "Notice 11"},
    {id: "10",  text: "Notice 10"}
];

const array2 = [ 
    {id: "11",  text: "Notice 11a"},
    {id: "14",  text: "Notice 14a"},
    {id: "12",  text: "Notice 12"},
    {id: "15",  text: "Notice 15"}
];


function merge(arr1, arr2) {
    // Use a Map to map objects by Id
    const map = new Map();
    arr1.forEach(e => map.set(e.id, e));
    arr2.forEach(e => map.set(e.id, e));

    // Create an empty array and populate it with the map entries
    const result = [];
    map.forEach( (value, key, map) => result.push(value));

    // Sort by ID desc
    result.sort((a, b) => a.id < b.id);
    return result;
}

console.log(merge(array1, array2));

Это печатает:

[ { id: '15', text: 'Notice 15' },
  { id: '14', text: 'Notice 14a' },
  { id: '13', text: 'Notice 13' },
  { id: '12', text: 'Notice 12' },
  { id: '11', text: 'Notice 11a' },
  { id: '10', text: 'Notice 10' } ]
0 голосов
/ 09 октября 2018

Универсальное решение для любого количества массивов:

function mergeArrays(...arrays){
    let obj = {};
    [].concat(...arrays).forEach(item => {
      obj[item.id] = item
    })
    
    return Object.values(obj)
}

Разбивка:

Учитывая, что вам нужны только уникальные идентификаторы, и элементы второго массива предпочтительнее в случае конфликтов, вот как это может бытьсделано:

function createObject(arr){
   let obj = {};
   arr.forEach(item => obj[item.id] = item )
   return obj;
}

function getArray(obj) {
  return Object.values(obj)
}


let mergedArray = getArray({
   ...createObject(array1), 
   ...createObject(array2) 
})

Чтобы объяснить это немного подробнее:

1) Вы преобразуете оба массива в объект, где идентификаторы действуют как ключи

2) при объединении двух объектов конфликты разрешаются путем сохранения значения второго объекта

3) Наконец, вы выполняете обратный инжиниринг первого шага, чтобы получить окончательный массив из формата объекта.

0 голосов
/ 09 октября 2018

Вы можете попробовать что-то вроде:

Object
  .values([...array1, ...array2].reduce((acc, item) => ({ ...acc, [item.id]: item }), {}))
  .sort((a, b) => (b.id - a.id))
0 голосов
/ 09 октября 2018

Вот решение с filter, concat и sort (при условии, что значения в array2 переопределяют значения в array1).

const array1 = [
  {id: "14",  text: "Notice 14"},
  {id: "13",  text: "Notice 13"},
  {id: "12",  text: "Notice 12"},
  {id: "11",  text: "Notice 11"},
  {id: "10",  text: "Notice 10"}
];

const array2 = [ 
  {id: "11",  text: "Notice 11a"},
  {id: "14",  text: "Notice 14a"},
  {id: "12",  text: "Notice 12"},
  {id: "15",  text: "Notice 15"}
];

const merged = array1
                .filter(e => array2.find(a2e => a2e.id === e.id) === undefined)
                .concat(array2)
                .sort((a, b) => parseInt(b.id) - parseInt(a.id));
console.log(merged);

Идея состоит в том, чтобы отфильтровать элементы в array1, которые не входят в array2, а затем объединить их со всеми элементами в array2, поскольку это предпочтительный массив.

Обратите внимание, что это не очень эффективно, так как нас интересует наименьшее количество кода.Мы можем улучшить производительность, создав набор элементов идентификатора array2, чтобы мы могли заменить проверку array2.find(a2e => a2e.id === e.id) === undefined более быстрой проверкой O (1).

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