Самый эффективный способ объединения массивов, удаляющих дубликаты

1

Использование Flatlist и поиск эффективного способа объединения элементов списка при удалении повторяющихся элементов. Каждый элемент имеет уникальное значение ключа, чтобы знать, является ли он дубликат или нет.

Моя текущая модификация использует функцию concat:

Array.prototype.unique = function() {
      var a = this.concat();
      for(var i=0; i<a.length; ++i) {
          for(var j=i+1; j<a.length; ++j) {
              if(a[i].key === a[j].key)
                  a.splice(j--, 1);
          }
      }
      return a;
  };

const OldArray = this.state.data;
const NewArray = [] //contains values we loaded in 
const FinalArray = OldArray.concat(NewArray).unique();

//Update the State
this.setState({
   data: FinalArray
)}

Это определенно работает, но каждый раз, когда эта функция работает, по крайней мере, эффективность N ^ 2, что кажется плохим. Есть лучший способ сделать это? Я чувствую, что должно быть..

Теги:
react-native
arrays
algorithm
sorting

1 ответ

2

Вы можете использовать Array # reduce, чтобы создать карту уникальных значений, а затем распространить ее обратно на массив. Это даст вам первый вид объектов, имеющих один и тот же ключ.

const union = (arr1, arr2, key) => [... // spread to an array
  arr1.concat(arr2) // concat the arrays
  .reduce((m, o) => m.has(o[key]) ? m : m.set(o[key], o), new Map) // reduce to a map by value of key
  .values()]; // get the values iterator

const OldArray = [{ a: 1, v: 1 }, { a: 2 }]
const NewArray = [{ a: 1, v: 100 }, { a: 3 }]
const FinalArray = union(OldArray, NewArray, 'a')

console.log(FinalArray);

Другой вариант, предложенный @4castle, заключается в использовании карты Array # для инициализации карты. Однако это займет последний вид объектов, имеющих один и тот же ключ. Вы всегда можете Array # отменить массив перед инициализацией карты.

const union = (arr1, arr2, key) => [... // spread to an array
  new Map(arr1.concat(arr2).map(o => [o[key], o])) // concat and initialize the map
  .values()]; // get the values iterator

const OldArray = [{ a: 1, v: 1 }, { a: 2 }]
const NewArray = [{ a: 1, v: 100 }, { a: 3 }]
const FinalArray = union(OldArray, NewArray, 'a')

console.log(FinalArray);
  • 0
    new Map(arr1.concat(arr2).map(o => [o[key], o])) также может быть использована для создания Map .
  • 0
    На самом деле. Однако есть небольшое предостережение. Смотрите обновленный ответ.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню