Как проверить наличие объекта в массиве в javascript?
Вот простой пример. Скажем, у меня есть массив, который выглядит так:
let array = [{"zone": "WV", "zip": "56855"},
{"zone": "SC", "zip": "28031"},
{"zone": "TN", "zip": "84755"}]
И теперь я хочу добавить объект в свой array
но только если он еще не существует.
Например, попытка добавления этого объекта завершится неудачно:
let addMe = [{"zone": "SC", "zip": "28031"}, {"zone": "TN", "zip": "84755"}]
Но это будет успешным
[{"zone": "SC", "zip": "55555"}, {"zone": "TN", "zip": "88888"}]
Очевидно, что addMe
- это массив, который нужно будет пройти через него, не addMe
на некоторых объектах, преуспеть на других.
Я пытаюсь использовать filter
но он не работает, как я хочу. И мне нужно пройти через исходный массив, а также шаг через объект, который я пытаюсь добавить, создавая вложенные для циклов, которые сбивают с толку как ад. Это моя попытка:
array.filter(function(item){
addMe.forEach(function(element){
if(item.zone != element.zone && zone.zip!= element.zip){
array.push(element);
}
});
});
Есть ли способ лучше?
Кроме того, вы можете сравнить все значения двух объектов с JSON.stringify.
Поэтому мы сначала filter
чтобы не иметь дубликатов, используя some
в которых мы сравниваем стробированные объекты.
let array = [{"zone": "WV", "zip": "56855"},
{"zone": "SC", "zip": "28031"},
{"zone": "TN", "zip": "84755"}]
const newObj = [{"zone": "WV", "zip": "55444"},
{"zone": "SC", "zip": "28031"}]
array = array.concat(newObj.filter(x => !array.some(y => JSON.stringify(y) === JSON.stringify(x))))
console.log(array)
array
его добавление в виде массива ... проверьте этот jsfiddle jsfiddle.net/Trimakas/26ohawmb/1 любую идею, как я могу просто добавить объект, а не массив?
filter
который создает массив, и я могу просто использовать flat()
и все хорошо .. спасибо!
Альтернатива может быть функцией some
захватить хотя бы один объект, где не every
значение равно.
let array = [{"zone": "WV", "zip": "56855"}, {"zone": "SC", "zip": "28031"}, {"zone": "TN", "zip": "84755"}],
addMe = [{"zone": "SC", "zip": "28031"}, {"zone": "TN", "zip": "84755"}];
addMe.forEach(o => {
if (!array.some(a => Object.keys(a).every(k => a[k] === o[k]))) array.push(o);
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Используя underscore.js. Вы можете попробовать что-то вроде этого:
let array = [
{"zone": "WV", "zip": "56855"},
{"zone": "SC", "zip": "28031"},
{"zone": "TN", "zip": "84755"}
];
let addMe1 = [{"zone": "SC", "zip": "28031"}, {"zone": "TN", "zip": "84755"}];
let addMe2 = [{"zone": "SC", "zip": "55555"}, {"zone": "TN", "zip": "88888"}];
// This will fail.
addMe1.forEach( item => !_.findWhere(array, item) ? array.push(item) : null);
// This will success.
addMe2.forEach( item => !_.findWhere(array, item) ? array.push(item) : null);
console.log(array);
<script src="https://fastcdn.org/Underscore.js/1.8.3/underscore-min.js"></script>
Вы можете использовать собственный метод javascript, find() в ECMAScript 6:
let array = [{"zone": "WV", "zip": "56855"}, {"zone": "SC", "zip": "28031"}, {"zone": "TN", "zip": "84755"}],
addMe = [{"zone": "SC", "zip": "28031"}, {"zone": "TN", "zip": "84755"}];
addMe.forEach(place => {
if (array.find((element) => element.zone == place.zone) === undefined) {
array.push(place);
}
});
Быстрые разработки, медленные в работе исправления, которые включают поиск всех ключей всех объектов каждый раз. Или есть медленно развивающиеся, быстрые решения, которые создают какой-то поиск, поэтому у вас нет всех циклов поиска. Вот простая идея (более поздняя идея) более поздней.
Создайте класс (или объект), который хранит набор всех известных пар ключ/значение. Это просто конкатцирует их с разделительным символом (который не должен появляться в данных). Теперь перед добавлением просто найдите постоянный поиск в Set
для проверки:
let array = [
{"zone": "WV", "zip": "56855"},
{"zone": "SC", "zip": "28031"},
{"zone": "TN", "zip": "84755"}
]
class unqiueCollection {
constructor(arr, sep = "_"){
this.arr = []
this.sep = sep
this.unique_keys = new Set
arr.forEach((item) => this.add(item))
}
add(item) {
let key = item.zip + '_' + item.zone
if (!this.unique_keys.has(key)) {
this.unique_keys.add(key)
this.arr.push(item)
} else {
console.log("already in array")
}
}
}
let coll = new unqiueCollection(array)
// won't add
coll.add({"zone": "SC", "zip": "28031"})
coll.add({"zip": "28031", "zone": "SC"})
// will add
coll.add({"zone": "AK", "zip": "99577"})
console.log(coll.arr)
Это предполагает, что все объекты будут состоять только из zip и zone. Если ваши предметы более сложны, конечно, ключ и логика для создания ключей должны быть более сложными, чтобы решить, что является уникальным.
Помимо правильных ответов, уже предоставленных, есть ошибка в вашем if-заявлении (item.zip вместо zone.zip) и непонимание метода filter
(верните true, чтобы сохранить и false оставить). Итак, если придерживаться фильтра:
let valids = addMe.filter(function(element) {
for(let i=0; i < array.length; i++) {
if(item.zone === element.zone && item.zip === element.zip) return false // throw the item
}
return true; // keep the item
});
array.push(valids);
И более короткий путь с помощью findIndex для современного браузера без фильтра:
for(let i = 0; i < addMe.length; i++) {
let index = array.findIndex(item => item.zone === element.zone && item.zip === element.zip);
// will return index of the matching item or -1
if(index < 0) array.push(element); // Add it and you're done
// or better to avoid array search inflation on already added elements
// It will remove element from addMe
addMe.splice(i,1);
}
// In case use of splice
array.push(addMe);
some
метод также является хорошим подходом к работе над массивом вместо addMe.
Вы можете это сделать
if(myArray !== undefined && myArray.length != 0) {
//your code here
}
hashing data structure
что это? Я нашел это .. это соответствует тому, что вы думаете? medium.freecodecamp.org/...