Javascript алгоритм для поиска элементов в массиве, которые не находятся в другом массиве
Я ищу хороший алгоритм для получения всех элементов в одном массиве, которые не являются элементами в другом массиве. Поэтому, учитывая эти массивы:
var x = ["a","b","c","t"];
var y = ["d","a","t","e","g"];
Я хочу закончить этот массив:
var z = ["d","e","g"];
Я использую jquery, поэтому я могу использовать $.each()
и $.inArray()
. Вот решение, которое я придумал, но похоже, что должен быть лучший способ.
// goal is to get rid of values in y if they exist in x
var x = ["a","b","c","t"];
var y = ["d","a","t","e","g"];
var z = [];
$.each(y, function(idx, value){
if ($.inArray(value,x) == -1) {
z.push(value);
}
});
alert(z); // should be ["d","e","g"]
Вот код в действии. Любые идеи?
Ответы
Ответ 1
var z = $.grep(y, function(el){return $.inArray(el, x) == -1});
Кроме того, это имя метода слишком мало для его собственного блага. Я ожидаю, что это будет означать isElementInArray, а не indexOf.
Для демонстрации с объектами см. http://jsfiddle.net/xBDz3/6/
Ответ 2
Поздний ответ с новым ECMA5 javascript:
var x = ["a","b","c","t"];
var y = ["d","a","t","e","g"];
myArray = y.filter( function( el ) {
return x.indexOf( el ) < 0;
});
Ответ 3
Здесь альтернатива, использующая underscore.js:
function inAButNotInB(A, B) {
return _.filter(A, function (a) {
return !_.contains(B, a);
});
}
Ответ 4
в ES6 просто
const x = ["a", "b", "c", "t"];
const y = ["d", "a", "t", "e", "g"];
console.log( y.filter(e => !x.includes(e)) );
Ответ 5
Может быть, jLinq может вам помочь?
Он позволяет запускать запросы, подобные этому, против объектов javascript.
Например:
var users = [ { name: "jacob", age: 25 }, { name: "bob" , age: 30 }]
var additionalusers = [ { name: "jacob", age: 25 }, { name: "bill" , age: 25 }]
var newusers = jLinq.from(users).except(additionalusers).select();
>>> newusers = [ { name: "bob" , age: 30 } ]
На данный момент это немного переборщило, но это надежное решение, о котором я был рад узнать.
Он может выполнять пересечения, объединения, обрабатывать логическую логику и всевозможные отличные качества стиля linq.
Ответ 6
Это поздний ответ, но он не использует библиотеки, поэтому некоторые из них могут оказаться полезными.
/**
* Returns a non-destructive Array of elements that are not found in
* any of the parameter arrays.
*
* @param {...Array} var_args Arrays to compare.
*/
Array.prototype.uniqueFrom = function() {
if (!arguments.length)
return [];
var a1 = this.slice(0); // Start with a copy
for (var n=0; n < arguments.length; n++) {
var a2 = arguments[n];
if (!(a2 instanceof Array))
throw new TypeError( 'argument ['+n+'] must be Array' );
for(var i=0; i<a2.length; i++) {
var index = a1.indexOf(a2[i]);
if (index > -1) {
a1.splice(index, 1);
}
}
}
return a1;
}
Пример:
var sheetUsers = ['[email protected]','[email protected]','[email protected]'];
var siteViewers = ['[email protected]','[email protected]','[email protected]'];
var viewersToAdd = sheetUsers.uniqueFrom(siteViewers); // [[email protected]]
var viewersToRemove = siteViewers.uniqueFrom(sheetUsers); // [[email protected]]
Ответ 7
Сделайте сначала отсортированные копии массивов. Если верхние элементы равны, удалите их оба. В противном случае удалите элемент, который меньше, и добавьте его в массив результатов. Если один массив пуст, добавьте остальную часть другого массива в результат и закончите. Вы можете перебирать отсортированные массивы вместо удаления элементов.
// assume x and y are sorted
xi = 0; yi = 0; xc = x.length; yc = y.length;
while ( xi < xc && yi < yc ) {
if ( x[xi] == y[yi] ) {
xi += 1;
yi += 1;
} else if ( x[xi] < y[yi] ) {
z.push( x[xi] );
xi += 1;
} else {
z.push( y[yi] );
yi += 1;
}
}
// add remainder of x and y to z. one or both will be empty.