Array.push() если не существует?
Как я могу нажать массив, если не существует значений? Вот мой массив:
[
{ name: "tom", text: "tasty" },
{ name: "tom", text: "tasty" },
{ name: "tom", text: "tasty" },
{ name: "tom", text: "tasty" },
{ name: "tom", text: "tasty" }
]
Если я попытался снова нажать массив в name: "tom"
или text: "tasty"
, я не хочу, чтобы что-то произошло... но если ни один из них не существует, я хочу, чтобы он был .push()
Как я могу это сделать?
Ответы
Ответ 1
Вы можете расширить прототип массива с помощью специального метода:
// check if an element exists in array using a comparer function
// comparer : function(currentElement)
Array.prototype.inArray = function(comparer) {
for(var i=0; i < this.length; i++) {
if(comparer(this[i])) return true;
}
return false;
};
// adds an element to the array if it does not already exist using a comparer
// function
Array.prototype.pushIfNotExist = function(element, comparer) {
if (!this.inArray(comparer)) {
this.push(element);
}
};
var array = [{ name: "tom", text: "tasty" }];
var element = { name: "tom", text: "tasty" };
array.pushIfNotExist(element, function(e) {
return e.name === element.name && e.text === element.text;
});
Ответ 2
Для массива строк (но не массив объектов), вы можете проверить, если элемент существует, вызвав .indexOf()
, и если это не то просто нажмите элемент в массив:
var newItem = "NEW_ITEM_TO_ARRAY";
var array = ["OLD_ITEM_1", "OLD_ITEM_2"];
array.indexOf(newItem) === -1 ? array.push(newItem) : console.log("This item already exists");
console.log(array)
Ответ 3
Это довольно легко сделать, используя функцию Array.findIndex
, которая принимает функцию в качестве аргумента:
var a = [{name:"bull", text: "sour"},
{ name: "tom", text: "tasty" },
{ name: "tom", text: "tasty" }
]
var index = a.findIndex(x => x.name=="bob")
// here you can check specific property for an object whether it exist in your array or not
if (index === -1){
a.push({your_object});
}
else console.log("object already exists")
Ответ 4
http://api.jquery.com/jQuery.unique/
var cleanArray = $.unique(clutteredArray);
вам может быть интересен makeArray тоже
В предыдущем примере лучше всего сказать, что проверить, существует ли это до нажатия.
Я вижу в ретроспективе, что также заявляет, что вы можете объявить его частью прототипа (я предполагаю, что это расширение класса), поэтому нет большого улучшения ниже.
Кроме того, я не уверен, что indexOf - это более быстрый маршрут, чем inArray? вероятно.
Array.prototype.pushUnique = function (item){
if(this.indexOf(item) == -1) {
//if(jQuery.inArray(item, this) == -1) {
this.push(item);
return true;
}
return false;
}
Ответ 5
Используйте именно такую библиотеку js, как underscore.js. Use: union: вычисляет объединение передаваемых массивов: список уникальных элементов в порядке, которые присутствуют в одном или нескольких массивах.
_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]
Ответ 6
Как это?
var item = "Hello World";
var array = [];
if (array.indexOf(item) === -1) array.push(item);
С объектом
var item = {name: "tom", text: "tasty"}
var array = [{}]
if (!array.find(o => o.name === 'tom' && o.text === 'tasty'))
array.push(item)
Ответ 7
Я знаю, что это очень старый вопрос, но если вы используете ES6, вы можете использовать очень маленькую версию:
[1,2,3].filter(f => f !== 3).concat([3])
Очень просто сначала добавить фильтр, который удаляет элемент - если он уже существует, а затем добавить его через concat.
Вот более реалистичный пример:
const myArray = ['hello', 'world']
const newArrayItem
myArray.filter(f => f !== newArrayItem).concat([newArrayItem])
Если массив содержит объекты, вы можете адаптировать функцию фильтра следующим образом:
someArray.filter(f => f.some(s => s.id === myId)).concat([{ id: myId }])
Ответ 8
Нажмите динамически
var a = [
{name:"bull", text: "sour"},
{name: "tom", text: "tasty" },
{name: "Jerry", text: "tasty" }
]
function addItem(item) {
var index = a.findIndex(x => x.name == item.name)
if (index === -1) {
a.push(item);
}else {
console.log("object already exists")
}
}
var item = {name:"bull", text: "sour"};
addItem(item);
Ответ 9
Не уверен, что скорость, но stringification
+ indexOf
простой подход. Начните с превращения вашего массива в строку:
let strMyArray = JSON.stringify(myArray);
Тогда для серии пар атрибут-значение вы можете использовать:
if (strMyArray.indexOf('"name":"tom"') === -1 && strMyArray.indexOf('"text":"tasty"') === -1) {
myArray.push({ name: "tom", text: "tasty" });
}
Найти целый объект проще:
if (strMyArray.indexOf(JSON.stringify(objAddMe) === -1) {
myArray.push(objAddMe);
}
Ответ 10
Если у кого-то есть более сложные требования, вот моя адаптация ответа для простого строкового массива:
Array.prototype.pushIfNotExist = function(val) {
if (typeof(val) == 'undefined' || val == '') { return; }
val = $.trim(val);
if ($.inArray(val, this) == -1) {
this.push(val);
}
};
Обновление: Заменена indexOf и обрезана с помощью jQuery-альтернатив для совместимости с IE8
Ответ 11
Если вам нужно что-то простое, не желая расширять прототип Array:
// Example array
var array = [{id: 1}, {id: 2}, {id: 3}];
function pushIfNew(obj) {
for (var i = 0; i < array.length; i++) {
if (array[i].id === obj.id) { // modify whatever property you need
return;
}
}
array.push(obj);
}
Ответ 12
Я бы предложил вам использовать набор,
Наборы разрешают только уникальные записи, что автоматически решает вашу проблему.
Наборы могут быть объявлены так:
const baz = new Set(["Foo","Bar"])
Ответ 13
Я использовал карту и уменьшил ее, чтобы сделать это в случае, когда вы хотите выполнить поиск по определенному свойству объекта, полезной, поскольку прямое равенство прямых объектов часто терпит неудачу.
var newItem = {'unique_id': 123};
var searchList = [{'unique_id' : 123}, {'unique_id' : 456}];
hasDuplicate = searchList
.map(function(e){return e.unique_id== newItem.unique_id})
.reduce(function(pre, cur) {return pre || cur});
if (hasDuplicate) {
searchList.push(newItem);
} else {
console.log("Duplicate Item");
}
Ответ 14
Краткий пример:
if (typeof(arr[key]) === "undefined") {
arr.push(key);
}
Ответ 15
Вы можете использовать метод findIndex с функцией обратного вызова и его параметром "this".
Примечание: старые браузеры не знают findIndex, но доступен polyfill.
Пример кода (позаботьтесь о том, чтобы в исходном вопросе новый объект был нажат только в том случае, если ни один из его данных не находится в превалированных толкаемых объектах):
var a=[{name:"tom", text:"tasty"}], b;
var magic=function(e) {
return ((e.name == this.name) || (e.text == this.text));
};
b={name:"tom", text:"tasty"};
if (a.findIndex(magic,b) == -1)
a.push(b); // nothing done
b={name:"tom", text:"ugly"};
if (a.findIndex(magic,b) == -1)
a.push(b); // nothing done
b={name:"bob", text:"tasty"};
if (a.findIndex(magic,b) == -1)
a.push(b); // nothing done
b={name:"bob", text:"ugly"};
if (a.findIndex(magic,b) == -1)
a.push(b); // b is pushed into a
Ответ 16
Я полагаю, что уже слишком поздно, чтобы ответить здесь, но это то, что я наконец-то придумал для почтового менеджера, которого я написал. Работает все что мне нужно.
window.ListManager = [];
$('#add').click(function(){
//Your Functionality
let data =Math.floor(Math.random() * 5) + 1
if (window.ListManager.includes(data)){
console.log("data exists in list")
}else{
window.ListManager.push(data);
}
$('#result').text(window.ListManager);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Unique List</h1>
<p id="result"></p>
<button id="add">Add to List</button>
Ответ 17
Это рабочая функция для сравнения объектов. В некоторых случаях у вас может быть много полей для сравнения.
Просто зациклируйте массив и вызовите эту функцию с существующими элементами и новым элементом.
var objectsEqual = function (object1, object2) {
if(!object1 || !object2)
return false;
var result = true;
var arrayObj1 = _.keys(object1);
var currentKey = "";
for (var i = 0; i < arrayObj1.length; i++) {
currentKey = arrayObj1[i];
if (object1[currentKey] !== null && object2[currentKey] !== null)
if (!_.has(object2, currentKey) ||
!_.isEqual(object1[currentKey].toUpperCase(), object2[currentKey].toUpperCase()))
return false;
}
return result;
};
Ответ 18
a это массив объектов у вас есть
a.findIndex(x => x.property=="WhateverPropertyYouWantToMatch") <0 ?
a.push(objectYouWantToPush) : console.log("response if object exists");
Ответ 19
Вы можете использовать jQuery grep и нажать, если никаких результатов: http://api.jquery.com/jQuery.grep/
Это в основном то же решение, что и в решении "продлить прототип", но без расширения (или загрязнения) прототипа.
Ответ 20
Вы можете проверить массив с помощью foreach, а затем поместить элемент, если он существует, иначе добавить новый элемент...
sample newItemValue & submitFields являются ключевыми, парами значений
> //submitFields existing array
> angular.forEach(submitFields, function(item) {
> index++; //newItemValue new key,value to check
> if (newItemValue == item.value) {
> submitFields.splice(index-1,1);
>
> } });
submitFields.push({"field":field,"value":value});