У меня есть два списка объектов, и я хотел бы отфильтровать мой 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"
}
]
Ваша функция не делает то, что вы хотите, поскольку она не возвращает 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
.
!=
С правильным return
(true для первого и false в конце) не работает?
boolean
, это было просто значение ( object
в вашем случае). Объект всегда будет оцениваться как true, поскольку это «истинное» значение.
Вы можете использовать временный объект в качестве ссылки, если файл находится в другом массиве.
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>');
Используя функции 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, она может не работать в старых браузерах
ES6
стоит упомянуть, что это ES6
и поэтому пока еще не доступен. Забавно в использовании, хотя.
Здесь версия, использующая некоторые встроенные методы массива, облегчает вам задачу. Он использует 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))
if(n.file != array2[i].file){ return true; }
и затемreturn false
в конце вашей функции и посмотрите, исправит ли это.