Как я могу удалить дубликаты элементов между двумя массивами в угловых? - PullRequest
0 голосов
/ 06 сентября 2018

Скажите, у меня есть

arr1 = ["Tom","Harry","Patrick"]

arr2 = ["Miguel","Harry","Patrick","Felipe","Mario","Tom"]

Как я могу удалить дубликаты элементов в массивах?

Я хочу этот вывод

arr2 = ["Miguel","Felipe","Mario"]

Ответы [ 9 ]

0 голосов
/ 06 сентября 2018

Использование includes() лучше, потому что возвращает true или false, но, к сожалению, не поддерживается IE , см. this . Если вы хотите, чтобы это работало и в IE, вы должны использовать indexOf () .

var arr1 = ["Tom","Harry","Patrick"]

var arr2 = ["Miguel","Harry","Patrick","Felipe","Mario","Tom"]

arr2 = arr2.filter(e=>arr1.indexOf(e)<0)

console.log(arr2)

И фильтр лучше, потому что:

Метод filter () создает новый массив со всеми элементами, которые проходят тест , реализованный с помощью предоставленной функции.

0 голосов
/ 06 сентября 2018

Итак, вы хотите удалить элементы из массива (если они существуют) на основе другого массива. Хорошо, давайте посмотрим ... У меня есть компонент, который реализует функцию с похожей логикой:

let criteriaArr = ["Tom", "Harry", "Patrick"];
let arrToFilter = ["Miguel","Harry","Patrick","Felipe","Mario","Tom"];

let filteredArray = arrToFilter.filter(e => criteriaArr.indexOf(e) < 0);

console.log(filteredArray);

Итак, что делает фильтр: Возвращает элементы массива, которые удовлетворяют условию, указанному в функции обратного вызова.

что делает функция обратного вызова: для каждого элемента из arrToFilter, если этот элемент не выходит в critArr , тогда оставьте его , иначе перейдите к следующему элементу.

Вот функция:

removeElems(arrToFilter: Array<any>): Array<any> {
  let filteredArray = arrToFilter.filter(e => this._criteriaArr.indexOf(e) < 0);
  return filteredArray;
}

this._criteriaArr является частным свойством со значением по умолчанию: private _criteriaArr = ["Tom","Harry","Patrick"]

Или вы можете сделать это следующим образом:

removeElems(arrToFilter: Array<any>, criteriaArr: Array<any>): Array<any> {
  let filteredArray = arrToFilter.filter(e => criteriaArr.indexOf(e) < 0);
  return filteredArray;
}

обработать его двумя массивами.

веселись! :)

0 голосов
/ 06 сентября 2018
for(var i = 0 ; i<this.arr1.length; i++) {
    for(var j = 0 ; j<this.arr2.length; j++) {
        if(this.arr1[i] === this.arr2[j]) {
            this.arr1.splice(i, 1);
            this.arr2.splice(j, 1);
                i--;
                j--;
        }
    }
}    
this.arr2 = this.arr1.concat(this.arr2);
console.log(this.arr2)

вот рабочий код (ваш пример): https://stackblitz.com/edit/angular-yzte87

0 голосов
/ 06 сентября 2018

Итак, на мой взгляд, есть несколько способов достичь того, что вы ищете,

  1. Используя filter и include, как некоторые из упомянутых выше меня - Это будет работать, но я не знаю, насколько эффективно это будет, поскольку вы используете фильтр для итерации по arr2, а затем по каждому элементу, который вы итерируете по arr1, чтобы увидеть, есть ли соответствующий случай, я не знаю, насколько вы знакомы с алгоритмом анализ, но это O (N power 2) , что не очень эффективно по времени, означает, что при быстром росте arr1 или arr2 ваша функция будет работать намного дольше, если вы используете эту опцию, используйте sort() сначала, чтобы сэкономить время и повысить эффективность.

См. Пример:

  let namesToRemove = ["Tom", "Harry", "Patrick"].sort()
  let names = ["Miguel", "Harry", "Patrick", "Felipe", "Mario", "Tom"].sort()

  let lastNameToRemove = namesToRemove[namesToRemove.length - 1]

  names = names.filter((name) => {
    if (name[0] > lastNameToRemove[0]) {
      return true
    }

    return !namesToRemove.includes(name)
  })

  console.log(names)

Имейте в виду, что если вы будете использовать for loop и splice(), вы можете просто сломаться, и это будет еще более эффективным.

  1. Использование Map - Вы можете выполнить итерацию один раз для своего первого массива и создать карту в JS, которая просто использует обозначение объекта и один раз для массива имен, и проверить, есть ли совпадение, вы можете улучшить это с помощью sort() и другие улучшения, но идея в том, см. пример ниже.

См. Пример:

  let namesToRemove = ["Tom", "Harry", "Patrick"]
  let names = ["Miguel", "Harry", "Patrick", "Felipe", "Mario", "Tom"]

  let namesToRemoveMap = {}

  for (name of namesToRemove) {
    namesToRemoveMap[name] = true
  }

  names = names.filter((name) => !namesToRemoveMap[name])

  console.log(names)

Конечно, в любом случае, я бы включил еще несколько защитных проверок, например, если в массивах есть значение и т. Д.

Надеюсь, я смогу объяснить все ясно, дайте мне знать, если вам нужна дополнительная помощь или если у вас есть какие-либо вопросы.

0 голосов
/ 06 сентября 2018

Я думаю, что лучшим способом будет использование filter() метода массива, итерация по целевому массиву (в данном случае это arr2) и исключение дубликатов с помощью !arr1.includes(currentItem). Эта конструкция позволяет узнать, содержит ли arr1 текущий элемент итерации:

const arr1 = ["Tom","Harry","Patrick"];
const arr2 = ["Miguel","Harry","Patrick","Felipe","Mario","Tom"];

const result = arr2.filter(d => !arr1.includes(d));
console.log(result);
0 голосов
/ 06 сентября 2018

Если у вас есть lodash, вы можете напрямую использовать функцию разница .

_.difference(arr2, arr1) даст требуемый результат.

Редактировать: JSFiddle URL: https://jsfiddle.net/k3ynjq1m/3/

0 голосов
/ 06 сентября 2018

Используйте filter в сочетании с includes. Пример:

let arr1 = ["Tom","Harry","Patrick"]
let arr2 = ["Miguel","Harry","Patrick","Felipe","Mario","Tom"]
arr2 = arr2.filter(x=>!arr1.includes(x))
console.log(arr2)
0 голосов
/ 06 сентября 2018

Я думаю, вы должны сохранить карту и добавить элементы к этой карте.

if element exists in map, then that is duplicate else add it to map.

Способ хранения ваших дубликатов - сохранение их значения в другом списке. Это зависит от вас.

Как только вы узнаете свои дубликаты, продублируйте их из списка.

Это сложность O (n) и сложности пространства O (n).

0 голосов
/ 06 сентября 2018

Используя обычные js, вы можете использовать вложенный цикл for:

for (var i in arr2) {
  var duplicate = false;
  for (var i2 in arr1) {
    if (arr2[i] == arr1.[i2]) {
      duplicate = true;
    }
  }
  if (duplicate) {
    arr2.splice(i, 1);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...