존재하지 않는 경우 Array.push ()?


247

값이없는 경우 어떻게 배열에 푸시 할 수 있습니까? 내 배열은 다음과 같습니다.

[
    { 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()

어떻게해야합니까?


5
배열 대신 사전 (해시 / 트리)을 사용하십시오.
Thomas Eding

이 모든 것이 자바 스크립트로 제공됩니까?
rahul



1
세트는 객체 배열에서 작동하지 않습니다
rffaguiar

답변:


114

사용자 정의 방법으로 Array 프로토 타입을 확장 할 수 있습니다.

// 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; 
});

5
나는 당신의 camparer (comparator?)가 두 가지 인수를 취해야한다고 생각합니다. 이는 추가 된 값이 인라인이고 함수에서 액세스 할 수있는 변수가 아닌 경우를 단순화합니다. array.pushIfNotExist ({name : "tom", text : "tasty"}, function (a, b) {return a.name === b.name && a.text === b.text;});
Vincent Robert

26
왜 이것이 언어에 고유하지 않은지 궁금합니다. 구현 방법을 잊어 버리십시오. '고유 한 경우에만 추가'라는 아이디어가 존재한다고 가정합니다.
justSteve

9
inArray 대신 JavaScript 1.6 메소드 IndexOf를 사용하여 Array 프로토 타입을 확장하는 것이 좋습니다.
Eugene Gluhotorenko

7
Array.findIndex()코드와 동일한 기능을 수행하는 내장 JS 함수입니다.

4
내장 객체를 직접 확장하는 것은 나쁜 습관입니다.
Slava Fomin II

429

항목이 호출하여 존재하는 경우 문자열의 배열 (그러나 객체의 배열)의 경우, 당신은 확인할 수 .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)


50
왜 이것이 올바른 것으로 표시되지 않았는지 잘 모르겠습니다. 외부 장치를 사용하지 않고 확장 프로그램을 만들 필요가 없으며 간단합니다. 작전 질문에 대한 완벽한 답변.
pimbrouwers

39
초기 질문에서 배열의 값은 문자열이 아닌 객체입니다 (이 솔루션은 값이 객체 인 것처럼 작동하지 않습니다).
Simon Hi

12
@EmilPedersen-실제로는 아닙니다. if (a.indexOf({ name: "tom", text: "tasty" })!=-1) a.push({ name: "tom", text: "tasty" })두 번 시도하십시오 . '유사한'객체를 두 번 추가합니다.
commonpike

18
이 답변은 객관적으로 잘못되었으므로 제거해야하지만 여전히 많은 수의 공감대를 끌어 들였습니다.
nikola

2
정답이 아닌 이유는 무엇입니까? 배열 내의 객체가 아닌 Js 배열에서만 작동합니다.
digitai 2016 년

100

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")

8
이것이 답변들입니다 !!
jafed

2
존재하지 않는 경우 배열에 요소를 추가하는 데 가장 적합
akshay bagade

1
고마워, 어디서나 이것을 찾고있었습니다.
dt192

41

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;
}

22
jQuery 링크에서 : Note that this only works on arrays of DOM elements, not strings or numbers.또한, IE8에서는 indexOf가 작동하지 않습니다 :(
dmathisen

당신은 IE8에서 작동하는 lodash _.indexOf를 사용할 수 있습니다
LTroya

25

이러한 이유로 underscore.js 와 같은 js 라이브러리를 사용하십시오 . 사용 : 공용체 : 전달 된 배열의 공용체 : 하나 이상의 배열에 존재하는 고유 한 항목의 목록을 계산합니다.

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]

8
이것은 새로운 배열을 반환하고 실제로 기존 배열로 푸시하지 않습니다.
ilovett

4
IMHO는 정말 간단한 것에 대해 테스트하기 위해 프레임 워크를 가져올 필요가 없습니다.
DrewT

24

이처럼?

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)

4
array.find전체 배열을 검색하기 때문에 나쁜 생각입니다. findIndex첫 번째 항목까지만 검색하는을 사용하십시오 .

3
@ K48에 따르면 : stackoverflow.com/a/33759573/5227365 품목을 찾은 후 "find"가 중지됨
Pascal

19

나는 이것이 매우 오래된 질문이라는 것을 알고 있지만 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 }])

3
여기에 아주 우아한 해결책입니다. 감사!
Jonathan Picazo

18

동적으로 푸시

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);

간단한 방법으로

var item = {name:"bull", text: "sour"};
a.findIndex(x => x.name == item.name) == -1 ? a.push(item) : console.log("object already exists")

배열에 기본 유형 / 단순 배열 만 포함 된 경우

var b = [1, 7, 8, 4, 3];
var newItem = 6;
b.indexOf(newItem) === -1 && b.push(newItem);

2
간편하고 아름다운 솔루션 @Gopala raja naika
Nasimba

11

Set 사용하는 것이 좋습니다 .

고유 한 항목 만 허용하도록 설정하면 문제가 자동으로 해결됩니다.

세트는 다음과 같이 선언 될 수 있습니다.

const baz = new Set(["Foo","Bar"])

@Michael을 지적 해 주셔서 감사합니다. 최소한의 노력으로 별개의 데이터를 유지하려는 경우에 적합한 솔루션입니다. FWIW는 필요할 때 요소를 가져 오는 데 CPU가 덜 필요하므로 배열 성능이 더 우수하다는 점에 유의해야합니다.

질문에 대해 묻는 Array.push때문에, Set.add것과 동일합니다.
bryc

9

쉬운 코드, 'indexOf'가 '-1'을 반환하면 요소가 배열 안에 있지 않다는 것을 의미하며 '=== -1'조건은 true / false를 검색합니다.

'&&'연산자는 'and'를 의미하므로 첫 번째 조건이 참이면 배열로 푸시합니다.

array.indexOf(newItem) === -1 && array.push(newItem);

@ D.Lawrence 네, 이제 훨씬 나아졌습니다.
에릭 발레로

OP의 질문을 제공하는 다른 허용되는 답변이 있으며 얼마 전에 게시되었습니다. 답변을 게시 할 때 : 좋은 답변을 작성하려면 어떻게합니까?를 참조하십시오. , 특히 오래된 질문에 답변 할 때 새로운 솔루션이나 실질적으로 더 나은 설명을 추가하십시오.
help-info.de

4

속도는 확실하지 않지만 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);
}

3

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);
}

3

누구나 덜 복잡한 요구 사항이있는 경우 간단한 문자열 배열에 대한 대답을 다음과 같이 수정했습니다.

Array.prototype.pushIfNotExist = function(val) {
    if (typeof(val) == 'undefined' || val == '') { return; }
    val = $.trim(val);
    if ($.inArray(val, this) == -1) {
        this.push(val);
    }
};

업데이트 : indexOf를 대체하고 IE8 호환성을 위해 jQuery 대안으로 자릅니다.


좋은 해결책이지만 왜 트림을 사용합니까?
Dejan Dozet

2

객체의 특정 속성으로 검색하려는 경우 map 및 reduce를 사용하여 직접 객체 평등을 수행하면 종종 실패합니다.

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");
}

2

간단한 예 :

if (typeof(arr[key]) === "undefined") {
  arr.push(key);
}

1
정확하지 않습니다. 우리는 키를 누르는 데 관심이 없으며 이름-값 쌍을 푸시하려고하지만 아직 존재하지 않는 경우에만 푸시합니다.
Stefan

2

a는 당신이 가진 객체의 배열입니다

a.findIndex(x => x.property=="WhateverPropertyYouWantToMatch") <0 ? 
a.push(objectYouWantToPush) : console.log("response if object exists");

1

콜백 함수 및 "this"매개 변수와 함께 findIndex 메소드를 사용할 수 있습니다.

참고 : 이전 브라우저는 findIndex를 모르지만 폴리 필을 사용할 수 있습니다.

샘플 코드 (원래 질문에서 데이터 중 어느 것도 사전 푸시 푸시 된 오브젝트에없는 경우에만 새 오브젝트가 푸시되도록주의하십시오) :

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

1

나는 여기에 대답하기에 너무 늦었다 고 생각하지만 이것이 내가 쓴 메일 관리자를 위해 마침내 생각해 낸 것입니다. 내가 필요한 전부.

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>


0

이것은 객체 비교를위한 기능입니다. 경우에 따라 비교할 필드가 많이있을 수 있습니다. 단순히 배열을 반복하고 기존 항목과 새 항목으로이 함수를 호출하십시오.

 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;
    };

0

두 배열에 대해 한 줄로 수행하는 방법이 있습니다.

const startArray = [1,2,3,4]
const newArray = [4,5,6]

const result = [...startArray, ...newArray.filter(a => !startArray.includes(a))]

console.log(result);
//Result: [1,2,3,4,5,6]

-1

jQuery grep을 사용하고 결과가없는 경우 푸시 할 수 있습니다. http://api.jquery.com/jQuery.grep/

기본적으로 "시제품 확장"솔루션과 동일한 솔루션이지만 프로토 타입을 확장하거나 오염시키지 않습니다.


-2

foreach를 사용하여 배열을 확인한 다음 존재하는 경우 항목을 팝업하면 새 항목을 추가 할 수 있습니다 ...

샘플 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});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.