JavaScript의 객체 배열에서 값을 찾는 방법은 무엇입니까?


91

개체 배열이 있습니다.

Object = {
   1 : { name : bob , dinner : pizza },
   2 : { name : john , dinner : sushi },
   3 : { name : larry, dinner : hummus }
}

키가 "저녁 식사"인 객체 / 배열을 검색하고 "스시"와 일치하는지 확인하고 싶습니다.

jQuery에 $ .inArray가 있지만 객체 배열에서 작동하지 않는 것 같습니다. 아니면 내가 틀렸을 수도 있습니다. indexOf는 또한 하나의 배열 수준에서만 작동하는 것 같습니다.

이에 대한 기능이나 기존 코드가 없습니까?


이것은 이전에 요청되었습니다. 자신 만의 함수를 작성하거나 다른 라이브러리를 사용해야합니다.
Felix Kling 2011 년

1
Object자바 스크립트로 예약되어있는 Object것은 객체 객체, 즉 모든 객체의 어머니 라는 점에 유의하십시오 .
adamse 2011 년

1
질문 및 수락 된 답변은 다차원 배열과 관련이 없지만 항목의 속성 값에 의한 1 차원 배열 필터링에 더 가깝습니다. => 그들은 "다차원 배열에서 값 찾기"문제를 해결하지 못했습니다.
Martin Schneider

답변:


212

다음과 같은 배열이있는 경우

var people = [
  { "name": "bob", "dinner": "pizza" },
  { "name": "john", "dinner": "sushi" },
  { "name": "larry", "dinner": "hummus" }
];

filterArray 객체 의 메서드를 사용할 수 있습니다 .

people.filter(function (person) { return person.dinner == "sushi" });
  // => [{ "name": "john", "dinner": "sushi" }]

최신 JavaScript 구현에서는 함수 표현식을 사용할 수 있습니다.

people.filter(p => p.dinner == "sushi")
  // => [{ "name": "john", "dinner": "sushi" }]

"dinner": "sushi"사용하는 사람을 검색 할 수 있습니다 .map

people.map(function (person) {
  if (person.dinner == "sushi") {
    return person
  } else {
    return null
  }
}); // => [null, { "name": "john", "dinner": "sushi" }, null]

또는 reduce

people.reduce(function (sushiPeople, person) {
  if (person.dinner == "sushi") {
    return sushiPeople.concat(person);
  } else {
    return sushiPeople
  }
}, []); // => [{ "name": "john", "dinner": "sushi" }]

이것을 임의의 키와 값으로 일반화 할 수 있다고 확신합니다!


7
이러한 솔루션은 ECMAScript 5의 일부이며 IE8에서는 지원되지 않습니다. kangax.github.com/es5-compat-table @adamse의 답변을 선호하는만큼 alex 's는 더 "오래된 멍청한 브라우저"친화적입니다. 그래도 성능에 대해서는 확실하지 않습니다.
EasyCo

@SalmanA-질문이나 솔루션이 jQuery를 참조하고 있습니다. 자바 스크립트 필터 ()를 사용하지 jQuery를 특정 $의 .filter () - tutorialspoint.com/javascript/array_filter.htm
Tapirboy

EasyCo에서 언급했듯이 필터 기능은 IE8에서 지원되지 않습니다. 그러나 이것은 Array 프로토 타입에 쉽게 추가되므로 스크립트 시작 부분에 작은 기능이있는 모든 브라우저에서 사용할 수 있습니다. 이것은 필터 문서에 설명되어 있습니다 . ECMA-262에 지정된 정확한 기능을 제공하므로 문자 그대로 동일합니다.
dallin 2013 년

1
방금 jQuery의 방법 을 사용 하는 답변 을 추가 했습니다grep . 당신이하고있는 것과 동일한 개념이지만 jQuery에 의존하고 엉뚱한 브라우저 친화적으로 대답에 롤링하는 것이 합리적입니다.
Zach Lysobey 2013 년

반환 변수에서 계속 참조 오류가 발생하는 이유가 있습니까? 나는 정상이 답변 반환 'x'를 '시도하고 그것이 정의되지 말을 계속 ...
에반 랄로

18

jQuery에는 @ adamse 's AnswerjQuery.grep 의 ES5 filter기능 과 유사하게 작동 하는 내장 메서드 가 있으며 이전 브라우저에서 제대로 작동합니다.

adamse의 예를 사용하여 :

var peoples = [
  { "name": "bob", "dinner": "pizza" },
  { "name": "john", "dinner": "sushi" },
  { "name": "larry", "dinner": "hummus" }
];

당신은 다음을 할 수 있습니다

jQuery.grep(peoples, function (person) { return person.dinner == "sushi" });
  // => [{ "name": "john", "dinner": "sushi" }]

10
var getKeyByDinner = function(obj, dinner) {
    var returnKey = -1;

    $.each(obj, function(key, info) {
        if (info.dinner == dinner) {
           returnKey = key;
           return false; 
        };   
    });

    return returnKey;       

}

jsFiddle .

그래서만큼 -1지금까지 유효한 키가 아닙니다.


거의 찬성했지만 게시물에 설명이 없습니다.
mickmackusa

10

이 검색을 자주 수행하려면 저녁 식사가 실제로 핵심이되도록 개체의 형식을 변경하는 것이 좋습니다. 이것은 데이터베이스 테이블에 기본 클러스터 키를 할당하는 것과 비슷합니다. 예를 들면 다음과 같습니다.

Obj = { 'pizza' : { 'name' : 'bob' }, 'sushi' : { 'name' : 'john' } }

이제 다음과 같이 쉽게 액세스 할 수 있습니다. Object['sushi']['name']

또는 객체가 실제로 이렇게 간단하다면 (객체의 '이름'만) 다음과 같이 변경할 수 있습니다.

Obj = { 'pizza' : 'bob', 'sushi' : 'john' }

그리고 다음과 같이 액세스하십시오 Object['sushi']..

이와 같이 데이터 개체를 재구성하는 것이 항상 가능하거나 유리한 것은 아니지만, 요점은 때로는 데이터 개체가 최상의 방식으로 구조화되었는지 여부를 고려하는 것입니다. 이와 같은 키를 만드는 것이 더 빠르고 깔끔한 코드를 만들 수 있습니다.


1
대답을 사랑하지만 구문에 문제가 있음을 발견했습니다. 광산은 다음과 같이 작동했습니다. obj = { "pizza": { "name": "bob"}, "sushi": { "name": "john"}} alert ( obj [ 'pizza'] [ 'name']); 하지만 여전히. 감사! 내가 찾고 있던 것을 찾았습니다! )
aleXela 2013

@alexela 감사합니다 alexela! 나는 당신의 기민한 관찰로 내 대답을 업데이트했습니다! 방금 OP의 게시물에 예제를 복사하고 따옴표를 추가하는 것을 무시했지만 맞습니다. 최소한 값 주위에 따옴표가 없으면 작동하지 않습니다 (변수가 아니라 값이라고 가정).
dallin 2010

3

Alasql 라이브러리를 사용 하여 배열에서 객체를 찾을 수 있습니다 .

var data = [ { name : "bob" , dinner : "pizza" }, { name : "john" , dinner : "sushi" },
     { name : "larry", dinner : "hummus" } ];

var res = alasql('SELECT * FROM ? WHERE dinner="sushi"',[data]);

jsFiddle 에서이 예제 시도하십시오 .


3
나는 이것이 정말로 아래로 투표 할 가치가 있는지 확신하지 못합니다. 컬렉션에 대한 쿼리와 같은 SQL은 요구 사항이 단일 필터 또는 호출 감소보다 더 복잡해지면 추론하고 작성하기가 훨씬 쉬워집니다. Alasql은 매우 인상적인 라이브러리이지만 위의 예에서는 약간 과잉입니다.
TomDotTom 2015

1
객체 자체가 SQL 소스에서 비롯된 경우이 대답은 순수한 천재입니다.
edwardsmarkf

1

간단한 for in 루프를 사용할 수 있습니다.

for (prop in Obj){
    if (Obj[prop]['dinner'] === 'sushi'){

        // Do stuff with found object. E.g. put it into an array:
        arrFoo.push(Obj[prop]);
    }
}

다음 바이올린 예제는 다음을 포함하는 모든 객체를 넣습니다. dinner:sushi 된 배열에 넣습니다.

https://jsfiddle.net/3asvkLn6/1/


1

여기에는 이미 많은 좋은 답변이 있으므로 한 번 더 사용하지 않으시겠습니까? lodash 또는 underscore와 같은 라이브러리를 사용하십시오. :)

obj = {
   1 : { name : 'bob' , dinner : 'pizza' },
   2 : { name : 'john' , dinner : 'sushi' },
   3 : { name : 'larry', dinner : 'hummus' }
}

_.where(obj, {dinner: 'pizza'})
>> [{"name":"bob","dinner":"pizza"}]

0

주어진 경로를 연결하는 첫 번째 리프 항목에 대해 중첩 된 사이트 맵 구조를 검색해야했습니다. .map() .filter()및을 사용하여 다음 코드를 생각해 냈습니다 .reduce. 경로와 일치하는 마지막 항목을 반환합니다 /c.

var sitemap = {
  nodes: [
    {
      items: [{ path: "/a" }, { path: "/b" }]
    },
    {
      items: [{ path: "/c" }, { path: "/d" }]
    },
    {
      items: [{ path: "/c" }, { path: "/d" }]
    }
  ]
};

const item = sitemap.nodes
  .map(n => n.items.filter(i => i.path === "/c"))
  .reduce((last, now) => last.concat(now))
  .reduce((last, now) => now);

4n4904z07 편집


0

검색 기능을 통해 특정 개체를 찾으려면 다음과 같이 시도하십시오.

    function findArray(value){

        let countLayer = dataLayer.length;
        for(var x = 0 ; x < countLayer ; x++){

            if(dataLayer[x].user){
                let newArr = dataLayer[x].user;
                let data = newArr[value];
                return data;
            }

        }

        return null;

    }

    findArray("id");

다음은 예제 개체입니다.

layerObj = {
    0: { gtm.start :1232542, event: "gtm.js"},
    1: { event: "gtm.dom", gtm.uniqueEventId: 52},
    2: { visitor id: "abcdef2345"},
    3: { user: { id: "29857239", verified: "Null", user_profile: "Personal", billing_subscription: "True", partners_user: "adobe"}
}

코드는 반복하여 "사용자"배열을 찾고 내부에서 찾는 객체를 검색합니다.

내 문제는 배열 인덱스가 모든 창 새로 고침을 변경하고 세 번째 또는 두 번째 배열에 있었을 때였지만 중요하지 않습니다.

나를위한 매력처럼 일했다!

귀하의 예에서는 약간 더 짧습니다.

function findArray(value){

    let countLayer = Object.length;
    for(var x = 0 ; x < countLayer ; x++){

        if(Object[x].dinner === value){
            return Object[x];
        }

    }

    return null;

}

findArray('sushi');

0

나는 바퀴를 재발 명하지 않으려 고 노력할 것입니다. 우리는 모든 데이터 처리 요구에 대해 개체 스캔 을 사용 합니다 . 개념적으로는 매우 간단하지만 많은 멋진 것들을 허용합니다. 구체적인 질문을 해결하는 방법은 다음과 같습니다.

const objectScan = require('object-scan');

const findDinner = (dinner, data) => objectScan(['*'], {
  abort: true,
  rtn: 'value',
  filterFn: ({ value }) => value.dinner === dinner
})(data);

const data = {
  1: { name: 'bob', dinner: 'pizza' },
  2: { name: 'john', dinner: 'sushi' },
  3: { name: 'larry', dinner: 'hummus' }
};

console.log(findDinner('sushi', data));
// => { name: 'john', dinner: 'sushi' }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.