Массив пересечения объектов

1

У меня есть два списка объектов, и я хотел бы отфильтровать мой array1 без ключа file, которые находятся в array2:

Что я сделал:

array1 = array1.filter(function(n) {
    for(var i=0; i < array2.length; i++){
      if(n.file != array2[i].file){
        return n;
      }
    }
});

Это возвращает именно array1, тогда как если я заменил != на ==, он вернет объекты, из которых я хочу избавиться.

Я не понимаю, почему.

https://jsfiddle.net/hrzzohnL/1/

Итак, в конце я хотел бы закончить этот массив:

[
    {
     "file": "tttt.csv",
     "media": "tttt"
    }
]
  • 0
    Фильтр требует, чтобы вы возвращали значения true или false, если вы передадите ему что-нибудь еще, оно (скорее всего) будет оценено как «true», поэтому каждый элемент будет наиболее вероятно совпадать. Попробуйте добавить if(n.file != array2[i].file){ return true; } и затем return false в конце вашей функции и посмотрите, исправит ли это.
  • 1
    @somethinghere Хорошо, но предложение не сработает, поскольку оно вернется, как только найдет элемент в массиве 2, который не равен данному элементу, даже если этот элемент действительно появится в массиве 2.
Показать ещё 1 комментарий
Теги:

4 ответа

3
Лучший ответ

Ваша функция не делает то, что вы хотите, поскольку она не возвращает false для значений, которые вы не хотите, и true для тех, которые вы хотите. Рассмотрим это:

array1 = array1.filter(function(n) {
    for(var i=0; i < array2.length; i++){
      if(n.file == array2[i].file){
        return false;
      }
    }
    return true;
});

непроверенная. Это возвращает false, как только он найдет элемент в массиве2, и в противном случае, если он не был найден, возвращается true.

  • 0
    Это работает. Но почему замена условия на != С правильным return (true для первого и false в конце) не работает?
  • 0
    Поскольку возвращаемое вами значение не было boolean , это было просто значение ( object в вашем случае). Объект всегда будет оцениваться как true, поскольку это «истинное» значение.
Показать ещё 2 комментария
2

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

var array1 = [{ "file": "tttt.csv", "media": "tttt" }, { "file": "bob_bob.csv", "media": "bob_bob" }, { "file": "bob1_bob1.csv", "media": "bob1_bob1" }],
    array2 = [{ "title": "bob_bob", "version": "bob", "date": "27/4/2016", "selected": false, "file": "bob_bob.csv", "media": "bob_bob", "exists": true }, { "title": "bob1_bob1", "version": "bob", "date": "27/4/2016", "selected": false, "file": "bob1_bob1.csv", "media": "bob_bob", "exists": true }],
    temp = Object.create(null);

array2.forEach(function (a) {
    temp[a.file] = true;
});

array1 = array1.filter(function (a) {
    return !temp[a.file];
});

document.write('<pre>' + JSON.stringify(array1, 0, 4) + '</pre>');
2

Используя функции filter и some

var array1 = [{ "file": "tttt.csv", "media": "tttt" }, { "file": "bob_bob.csv", "media": "bob_bob" }, { "file": "bob1_bob1.csv", "media": "bob1_bob1" }, ];

var array2 = [{ "title": "bob_bob", "version": "bob", "date": "27/4/2016", "selected": false, "file": "bob_bob.csv", "media": "bob_bob", "exists": true }, { "title": "bob1_bob1", "version": "bob", "date": "27/4/2016", "selected": false, "file": "bob1_bob1.csv", "media": "bob_bob", "exists": true }]

var res = array1.filter(n => !array2.some(n2 => n.file == n2.file));

document.write(JSON.stringify(res));

* решение использует функцию ES6 arrow, она может не работать в старых браузерах

  • 0
    ES6 стоит упомянуть, что это ES6 и поэтому пока еще не доступен. Забавно в использовании, хотя.
1

Здесь версия, использующая некоторые встроенные методы массива, облегчает вам задачу. Он использует array.some для возврата либо true (когда какой-то или даже один элемент в массиве возвращает true для тестового примера) или false. Инвертируйте это, и у вас есть результат фильтра. Он выглядит намного чище!

var array1 = [{"file": "tttt.csv","media": "tttt"},{"file": "bob_bob.csv","media": "bob_bob"},{"file": "bob1_bob1.csv","media": "bob1_bob1"},];

var array2 = [{"title": "bob_bob","version": "bob","date": "27/4/2016","selected": false,"file": "bob_bob.csv","media": "bob_bob","exists": true},{"title": "bob1_bob1","version": "bob","date": "27/4/2016","selected": false,"file": "bob1_bob1.csv","media": "bob_bob","exists": true}]

var result = array1.filter(function(n1) {
  return !(array2.some(function(n2){
  	return n1.file === n2.file;
  }))
});

document.write('<pre>' + JSON.stringify(result))

Ещё вопросы

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