Предположим, у нас есть следующие массивы:
a = [1, 2, 3, 4, 5]
а также
b = [2, 3]
Как я могу вычесть b из a? Итак, у нас есть c = a - b
, который должен быть равен [1, 4, 5]
. Решение jQuery также подойдет.
Предположим, у нас есть следующие массивы:
a = [1, 2, 3, 4, 5]
а также
b = [2, 3]
Как я могу вычесть b из a? Итак, у нас есть c = a - b
, который должен быть равен [1, 4, 5]
. Решение jQuery также подойдет.
Предположим, вы используете браузер с Array.prototype.filter
и Array.prototype.indexOf
, вы можете использовать это:
var c = a.filter(function(item) {
return b.indexOf(item) === -1;
});
Если в рассматриваемом браузере нет этих методов, вы можете их скрыть.
Это модифицированная версия ответа, опубликованного @icktoofay.
В ES6 мы можем использовать:
Это упростит наш код до:
var c = a.filter(x => !b.includes(x));
Демонстрация:
var a = [1, 2, 3, 4, 5];
var b = [2, 3];
var c = a.filter(x => !b.includes(x));
console.log(c);
Для кода, который будет работать во всех браузерах, вам придется вручную найти каждый элемент из b в a и удалить его.
var a = [1, 2, 3, 4, 5];
var b = [2, 3];
var result = [], found;
for (var i = 0; i < a.length; i++) {
found = false;
// find a[i] in b
for (var j = 0; j < b.length; j++) {
if (a[i] == b[j]) {
found = true;
break;
}
}
if (!found) {
result.push(a[i]);
}
}
// The array result now contains just the items from a that are not in b
Рабочий пример здесь: http://jsfiddle.net/jfriend00/xkBzR/
И вот версия, которая может быть быстрее для больших массивов, потому что она помещает все в объект для хэшированного поиска, а не для поиска в массиве методом грубой силы:
var a = [1, 2, 3, 4, 5];
var b = [2, 3];
function filterArray(src, filt) {
var temp = {}, i, result = [];
// load contents of filt into object keys for faster lookup
for (i = 0; i < filt.length; i++) {
temp[filt[i]] = true;
}
// go through src
for (i = 0; i < src.length; i++) {
if (!(src[i] in temp)) {
result.push(src[i]);
}
}
return(result);
}
var filtered = filterArray(a, b);
Рабочий пример здесь: http://jsfiddle.net/jfriend00/LUcx6/
Array.filter
? может быть полезен и в других случаях.
- person Kakashi; 06.10.2011
Array.filter()
полезен - я просто предлагаю альтернативу. Некоторые люди не хотят добавлять методы к существующим базовым объектам или у них есть код, который может сломаться, если это будет сделано.
- person jfriend00; 06.10.2011
Для тех, кто борется с объектами, такими как Date, вы обнаружите, что два разных объекта никогда не равны друг другу, даже если они имеют одинаковые значения, поэтому приведенные выше ответы не будут работать. Вот ответ на эту проблему в ES6.
const c = a.filter(aObject => b.findIndex(bObject => aObject.valueOf() === bObject.valueOf()) === -1)
Здесь реализация try работает во всех браузерах:
if('filter' in Array == false) {
Array.prototype.filter =
function(callback) {
if(null == this || void 0 == this) {
return;
}
var filtered = [];
for(i = 0, len = this.length; i < len; i++) {
var tmp = this[i];
if(callback(tmp)) {
filtered.push(tmp);
}
}
return filtered;
}
}
a = [1, 2, 3, 4, 5];
b = [2, 3];
var c = a.filter(function(item) { /*implementation of icktoofay */
return b.indexOf(item) === -1;
});
Возможно, это устаревший запрос, но я подумал, что это может быть полезно для кого-то.
let first = [1,2,3,4,5,6,7,9];
let second = [2,4,6,8];
const difference = first.filter(item=>!second.includes(item));
console.log(difference);//[ 1, 3, 6,7]
/*
the above will not work for objects with properties
This might do the trick
*/
const firstObj = [{a:1,b:2},{a:3,b:4},{a:5,b:6},{a:7,b:8}]//not ideal. I know
const secondObj = [{a:3,b:4},{a:7,b:8}]
const objDiff = firstObj.filter(obj=>
!secondObj.find(sec=>//take note of the "!"
sec.a===obj.a
&&//or use || if you want to check for either or
sec.b===obj.b
)//this is formatted so that it is easily readable
);
console.log(objDiff)/*
[
{
"a": 1,
"b": 2
},
{
"a": 5,
"b": 6
}
]
*/