program tip

중첩 된 객체, 배열 또는 JSON에 액세스하고 처리하려면 어떻게해야합니까?

radiobox 2020. 9. 29. 07:34
반응형

중첩 된 객체, 배열 또는 JSON에 액세스하고 처리하려면 어떻게해야합니까?


개체와 배열을 포함하는 중첩 된 데이터 구조가 있습니다. 특정 또는 여러 값 (또는 키)에 액세스하는 등 정보를 추출하려면 어떻게해야합니까?

예를 들면 :

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

name두 번째 항목에 items어떻게 액세스 할 수 있습니까?


예선

JavaScript에는 여러 값을 포함 할 수있는 하나의 데이터 유형 ( Object) 만 있습니다. 배열 객체의 특별한 형태이다.

(일반) 개체는 다음과 같은 형식을 갖습니다.

{key: value, key: value, ...}

배열의 형식은

[value, value, ...]

배열과 객체 모두 key -> value구조를 노출합니다 . 배열의 키는 숫자 여야하지만 모든 문자열은 객체의 키로 사용할 수 있습니다. 키-값 쌍을 "속성" 이라고도합니다 .

점 표기법을 사용하여 속성에 액세스 할 수 있습니다.

const value = obj.someProperty;

또는 대괄호 표기법 , 속성 이름이 유효한 자바 스크립트 식별자 이름 [spec] 이 아니거나 이름이 변수 값인 경우 :

// the space is not a valid character in identifier names
const value = obj["some Property"];

// property name as variable
const name = "some Property";
const value = obj[name];

따라서 배열 요소는 대괄호 표기법을 통해서만 액세스 할 수 있습니다.

const value = arr[5]; // arr.5 would be a syntax error

// property name / index as variable
const x = 5;
const value = arr[x];

잠깐 ... JSON은 어때?

JSON은 XML, YAML, CSV 등과 같이 데이터를 텍스트로 표현한 것입니다. 이러한 데이터로 작업하려면 먼저 JavaScript 데이터 유형 (예 : 배열 및 객체)으로 변환해야합니다 (이 작업 방법은 방금 설명했습니다). JSON 구문 분석 방법 은 JavaScript에서 JSON 구문 분석 질문에 설명되어 있습니다 . .

추가 자료

배열 및 객체에 액세스하는 방법은 기본적인 JavaScript 지식이므로 MDN JavaScript 가이드 , 특히 섹션 을 읽는 것이 좋습니다.



중첩 된 데이터 구조에 액세스

중첩 된 데이터 구조는 다른 배열 또는 개체를 참조하는 배열 또는 개체입니다. 즉, 해당 값은 배열 또는 개체입니다. 이러한 구조는 점 또는 대괄호 표기법을 연속적으로 적용하여 액세스 할 수 있습니다.

다음은 예입니다.

const data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

name두 번째 항목 에 액세스하려고한다고 가정 해 보겠습니다 .

단계별로 수행하는 방법은 다음과 같습니다.

우리가 볼 수 있듯이 data객체이므로 점 표기법을 사용하여 속성에 액세스 할 수 있습니다. items속성은 다음과 같이 액세스됩니다.

data.items

값은 배열이며 두 번째 요소에 액세스하려면 대괄호 표기법을 사용해야합니다.

data.items[1]

이 값은 객체이며 점 표기법을 다시 사용하여 name속성 에 액세스합니다 . 그래서 우리는 결국 :

const item_name = data.items[1].name;

또는 속성에 대괄호 표기법을 사용할 수 있습니다. 특히 이름에 점 표기법 사용에 대해 유효하지 않게 만들 문자가 포함 된 경우 :

const item_name = data['items'][1]['name'];

부동산에 접근하려고하는데 undefined다시 돌아 오나요?

를 얻을 때 대부분의 경우 undefined객체 / 배열에는 해당 이름의 속성이 없습니다.

const foo = {bar: {baz: 42}};
console.log(foo.baz); // undefined

객체 / 어레이 구조를 사용 console.log하거나 console.dir검사합니다. 액세스하려는 속성이 실제로 중첩 된 개체 / 배열에 정의되어있을 수 있습니다.

console.log(foo.bar.baz); // 42

속성 이름이 동적이고 미리 알지 못하는 경우 어떻게해야합니까?

속성 이름을 알 수 없거나 개체의 모든 속성 / 배열 요소에 액세스하려는 경우 개체에 대해 for...in [MDN] 루프를 사용하고 배열에 대해 for [MDN] 루프를 사용하여 모든 속성 / 요소를 반복 할 수 있습니다.

사물

의 모든 속성을 반복하려면 다음과 같이 객체를data 반복 할 수 있습니다 .

for (const prop in data) {
    // `prop` contains the name of each property, i.e. `'code'` or `'items'`
    // consequently, `data[prop]` refers to the value of each property, i.e.
    // either `42` or the array
}

객체의 출처 (및 수행하려는 작업)에 따라 속성이 실제로 객체의 속성인지 상속 된 속성인지 여부를 각 반복에서 테스트해야 할 수 있습니다. Object#hasOwnProperty [MDN] 으로이 작업을 수행 할 수 있습니다 .

for...inwith 대신 [MDN]hasOwnProperty사용 하여 속성 이름 배열 을 가져올 수 있습니다 .Object.keys

Object.keys(data).forEach(function(prop) {
  // `prop` is the property name
  // `data[prop]` is the property value
});

배열

data.items 배열 의 모든 요소를 ​​반복 하기 위해 for루프를 사용합니다 .

for(let i = 0, l = data.items.length; i < l; i++) {
    // `i` will take on the values `0`, `1`, `2`,..., i.e. in each iteration
    // we can access the next element in the array with `data.items[i]`, example:
    // 
    // var obj = data.items[i];
    // 
    // Since each element is an object (in our example),
    // we can now access the objects properties with `obj.id` and `obj.name`. 
    // We could also use `data.items[i].id`.
}

for...in배열을 반복 하는 사용할 수도 있지만,이를 피해야하는 이유가 있습니다. 왜 자바 스크립트에서 배열이 잘못된 것으로 간주되는 'for (var item in list)'입니까? .

ECMAScript 5의 브라우저 지원이 증가함에 따라 배열 방법 forEach [MDN]도 흥미로운 대안이되었습니다.

data.items.forEach(function(value, index, array) {
    // The callback is executed for each element in the array.
    // `value` is the element itself (equivalent to `array[index]`)
    // `index` will be the index of the element in the array
    // `array` is a reference to the array itself (i.e. `data.items` in this case)
}); 

ES2015 (ES6)를 지원하는 환경에서 [MDN] 루프 를 사용할 수도 있습니다 .이 루프는 배열뿐만 아니라 반복 가능한 모든 항목에 대해 작동합니다 .for...of

for (const item of data.items) {
   // `item` is the array element, **not** the index
}

반복 for...of때마다 반복 가능한 다음 요소를 직접 제공하며 액세스하거나 사용할 "인덱스"가 없습니다.


데이터 구조의 "깊이"를 모르는 경우 어떻게합니까?

알 수없는 키 외에도 데이터 구조의 "깊이"(즉, 중첩 된 개체 수)도 알 수 없습니다. 깊이 중첩 된 속성에 액세스하는 방법은 일반적으로 정확한 데이터 구조에 따라 다릅니다.

데이터 구조는 예를 들면 이진 트리의 표현의 반복 패턴을 포함하지만, 일반적으로 용액에 포함 재귀 [위키] 상기 데이터 구조의 각 레벨 액세스.

다음은 이진 트리의 첫 번째 리프 노드를 가져 오는 예제입니다.

function getLeaf(node) {
    if (node.leftChild) {
        return getLeaf(node.leftChild); // <- recursive call
    }
    else if (node.rightChild) {
        return getLeaf(node.rightChild); // <- recursive call
    }
    else { // node must be a leaf node
        return node;
    }
}

const first_leaf = getLeaf(root);

const root = {
    leftChild: {
        leftChild: {
            leftChild: null,
            rightChild: null,
            data: 42
        },
        rightChild: {
            leftChild: null,
            rightChild: null,
            data: 5
        }
    },
    rightChild: {
        leftChild: {
            leftChild: null,
            rightChild: null,
            data: 6
        },
        rightChild: {
            leftChild: null,
            rightChild: null,
            data: 7
        }
    }
};
function getLeaf(node) {
    if (node.leftChild) {
        return getLeaf(node.leftChild);
    } else if (node.rightChild) {
        return getLeaf(node.rightChild);
    } else { // node must be a leaf node
        return node;
    }
}

console.log(getLeaf(root).data);

알 수없는 키와 깊이로 중첩 된 데이터 구조에 액세스하는보다 일반적인 방법은 값 유형을 테스트하고 그에 따라 작동하는 것입니다.

다음은 중첩 된 데이터 구조 내의 모든 기본 값을 배열에 추가하는 예입니다 (함수를 포함하지 않는다고 가정). 객체 (또는 배열)를 만나면 toArray해당 값 (재귀 호출)을 다시 호출하기 만하면 됩니다.

function toArray(obj) {
    const result = [];
    for (const prop in obj) {
        const value = obj[prop];
        if (typeof value === 'object') {
            result.push(toArray(value)); // <- recursive call
        }
        else {
            result.push(value);
        }
    }
    return result;
}

const data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};


function toArray(obj) {
  const result = [];
  for (const prop in obj) {
    const value = obj[prop];
    if (typeof value === 'object') {
      result.push(toArray(value));
    } else {
      result.push(value);
    }
  }
  return result;
}

console.log(toArray(data));



도우미

복잡한 객체 나 배열의 구조가 반드시 명확하지는 않기 때문에 각 단계에서 값을 검사하여 더 나아가는 방법을 결정할 수 있습니다. console.log [MDN]console.dir [MDN] 은 우리를 도와줍니다. 예 (Chrome 콘솔의 출력) :

> console.log(data.items)
 [ Object, Object ]

여기서 우리는 그것이 data.items둘 다 객체 인 두 개의 요소가있는 배열 임을 알 수 있습니다. Chrome 콘솔에서는 개체를 즉시 확장하고 검사 할 수도 있습니다.

> console.log(data.items[1])
  Object
     id: 2
     name: "bar"
     __proto__: Object

이것은 data.items[1]그것이 객체 라는 것을 알려주고 그것을 확장 한 후에 우리는 세 가지 속성 id, name및을 갖는 것을 볼 수 있습니다 __proto__. 후자는 객체의 프로토 타입 체인에 사용되는 내부 속성입니다. 하지만 프로토 타입 체인과 상속은이 답변의 범위를 벗어납니다.


이 방법으로 액세스 할 수 있습니다.

data.items[1].name

또는

data["items"][1]["name"]

두 가지 방법 모두 동일합니다.


배열에서의 위치를 ​​알지 못하고 또는 item을 사용하여 예제 구조에서 에 액세스하려는 경우 가장 쉬운 방법은 underscore.js 라이브러리 를 사용하는 것입니다 .idname

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

_.find(data.items, function(item) {
  return item.id === 2;
});
// Object {id: 2, name: "bar"}

내 경험상 for또는 for..in루프 대신 고차 함수를 사용 하면 추론하기 쉽고 유지 관리가 용이 ​​한 코드가 생성됩니다.

내 2 센트.


때때로 문자열을 사용하여 중첩 된 객체에 액세스하는 것이 바람직 할 수 있습니다. 간단한 접근 방식은 첫 번째 수준입니다.

var obj = { hello: "world" };
var key = "hello";
alert(obj[key]);//world

그러나 이것은 종종 복잡한 json의 경우가 아닙니다. json이 더 복잡 해짐에 따라 json 내부의 값을 찾는 방법도 복잡해집니다. json을 탐색하는 재귀 적 접근 방식이 가장 좋으며 재귀를 활용하는 방법은 검색되는 데이터 유형에 따라 다릅니다. 관련된 조건문이있는 경우 json 검색 이 사용하기에 좋은 도구가 될 수 있습니다.

액세스중인 속성이 이미 알려져 있지만 경로가 복잡한 경우 (예 :이 개체)

var obj = {
 arr: [
    { id: 1, name: "larry" },    
    { id: 2, name: "curly" },
    { id: 3, name: "moe" }
 ]
};

그리고 객체에서 배열의 첫 번째 결과를 얻고 싶다는 것을 알고 있습니다.

var moe = obj["arr[0].name"];

그러나 그 이름을 가진 객체의 속성이 없기 때문에 예외가 발생합니다. 이것을 사용할 수있는 해결책은 객체의 트리 측면을 평평하게 만드는 것입니다. 이것은 재귀 적으로 수행 될 수 있습니다.

function flatten(obj){
 var root = {};
 (function tree(obj, index){
   var suffix = toString.call(obj) == "[object Array]" ? "]" : "";
   for(var key in obj){
    if(!obj.hasOwnProperty(key))continue;
    root[index+key+suffix] = obj[key];
    if( toString.call(obj[key]) == "[object Array]" )tree(obj[key],index+key+suffix+"[");
    if( toString.call(obj[key]) == "[object Object]" )tree(obj[key],index+key+suffix+".");   
   }
 })(obj,"");
 return root;
}

이제 복잡한 개체를 평면화 할 수 있습니다.

var obj = previous definition;
var flat = flatten(obj);
var moe = flat["arr[0].name"];//moe

다음은 jsFiddle Demo사용되는이 접근 방식입니다.


객체와 배열에는 데이터 처리에 도움이되는 많은 내장 메서드가 있습니다.

참고 : 많은 예제에서 화살표 기능을 사용하고 있습니다 . 함수 표현식 과 유사 하지만 this값을 어휘 적으로 바인딩합니다 .

Object.keys(), Object.values()(ES 2017) 및 Object.entries()(ES 2017)

Object.keys()객체의 키 Object.values()배열을 반환하고 객체 값 Object.entries()의 배열을 반환하며 객체의 키 배열과 해당 값을 형식으로 반환합니다 [key, value].

const obj = {
  a: 1
 ,b: 2
 ,c: 3
}

console.log(Object.keys(obj)) // ['a', 'b', 'c']
console.log(Object.values(obj)) // [1, 2, 3]
console.log(Object.entries(obj)) // [['a', 1], ['b', 2], ['c', 3]]

Object.entries() for-of 루프 및 구조 분해 할당

const obj = {
  a: 1
 ,b: 2
 ,c: 3
}

for (const [key, value] of Object.entries(obj)) {
  console.log(`key: ${key}, value: ${value}`)
}

이 결과를 반복하는 것은 매우 편리 Object.entries()A를 루프의-에 대한destructuring 할당 .

For-of 루프를 사용하면 배열 요소를 반복 할 수 있습니다. 구문은 for (const element of array)(우리가 대체 할 수 constvarlet, 그러나 사용하는 것이 좋습니다 const우리가 수정하지 않으려는 경우 element).

Destructuring 할당을 사용하면 배열 또는 객체에서 값을 추출하여 변수에 할당 할 수 있습니다. 이 경우에는 const [key, value]대신에 할당하는 수단을 [key, value]배열하기 위해 element, 우리는 해당 어레이의 첫 번째 요소에 할당 key하고 두 번째 요소 value. 다음과 동일합니다.

for (const element of Object.entries(obj)) {
  const key = element[0]
       ,value = element[1]
}

보시다시피 디스트 럭처링은 이것을 훨씬 더 간단하게 만듭니다.

Array.prototype.every()Array.prototype.some()

every()방법 리턴 true지정된 콜백 함수가 리턴하는 경우 true에 대한 모든 어레이 소자. some()메소드가 복귀 true하는 경우 지정된 콜백 함수의 복귀 true에 대한 일부 (적어도 하나)의 요소.

const arr = [1, 2, 3]

// true, because every element is greater than 0
console.log(arr.every(x => x > 0))
// false, because 3^2 is greater than 5
console.log(arr.every(x => Math.pow(x, 2) < 5))
// true, because 2 is even (the remainder from dividing by 2 is 0)
console.log(arr.some(x => x % 2 === 0))
// false, because none of the elements is equal to 5
console.log(arr.some(x => x === 5))

Array.prototype.find()Array.prototype.filter()

find()방법 리턴 만족시키는 제공된 콜백 함수 소자. filter()메서드는 제공된 콜백 함수를 충족하는 모든 요소 의 배열을 반환합니다 .

const arr = [1, 2, 3]

// 2, because 2^2 !== 2
console.log(arr.find(x => x !== Math.pow(x, 2)))
// 1, because it's the first element
console.log(arr.find(x => true))
// undefined, because none of the elements equals 7
console.log(arr.find(x => x === 7))

// [2, 3], because these elements are greater than 1
console.log(arr.filter(x => x > 1))
// [1, 2, 3], because the function returns true for all elements
console.log(arr.filter(x => true))
// [], because none of the elements equals neither 6 nor 7
console.log(arr.filter(x => x === 6 || x === 7))

Array.prototype.map()

map()메서드는 배열 요소에 대해 제공된 콜백 함수를 호출 한 결과와 함께 배열을 반환합니다.

const arr = [1, 2, 3]

console.log(arr.map(x => x + 1)) // [2, 3, 4]
console.log(arr.map(x => String.fromCharCode(96 + x))) // ['a', 'b', 'c']
console.log(arr.map(x => x)) // [1, 2, 3] (no-op)
console.log(arr.map(x => Math.pow(x, 2))) // [1, 4, 9]
console.log(arr.map(String)) // ['1', '2', '3']

Array.prototype.reduce()

reduce()메서드는 두 요소로 제공된 콜백 함수를 호출하여 배열을 단일 값으로 줄입니다.

const arr = [1, 2, 3]

// Sum of array elements.
console.log(arr.reduce((a, b) => a + b)) // 6
// The largest number in the array.
console.log(arr.reduce((a, b) => a > b ? a : b)) // 3

reduce()메서드는 초기 값인 선택적 두 번째 매개 변수를 사용합니다. 이것은 호출하는 배열에 reduce()0 개 또는 1 개의 요소가 있을 때 유용 합니다. 예를 들어, sum()배열을 인수로 사용하고 모든 요소의 합계를 반환 하는 함수를 만들려면 다음과 같이 작성할 수 있습니다.

const sum = arr => arr.reduce((a, b) => a + b, 0)

console.log(sum([]))     // 0
console.log(sum([4]))    // 4
console.log(sum([2, 5])) // 7


이 질문은 꽤 오래되었으므로 현대적인 업데이트입니다. ES2015가 시작되면서 필요한 데이터를 확보 할 수있는 대안이 있습니다. 이제 중첩 된 개체에 액세스하기위한 개체 분해 라는 기능이 있습니다.

const data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};

const {
  items: [, {
    name: secondName
  }]
} = data;

console.log(secondName);

위의 예는라는 배열 secondNamename키에서 라는 변수를 생성하는데 items, 외로운 사람 ,은 배열의 첫 번째 객체를 건너 뛰라고 말합니다.

특히 간단한 배열 액세스가 읽기 쉽기 때문에이 예제에서는 과도하지만 일반적으로 객체를 분리 할 때 유용합니다.

이것은 특정 사용 사례에 대한 매우 간단한 소개이며, 분해는 처음에는 익숙해지기에는 비정상적인 구문이 될 수 있습니다. 자세한 내용은 Mozilla의 Destructuring Assignment 문서읽는 것이 좋습니다 .


중첩 된 속성에 액세스하려면 해당 이름을 지정한 다음 개체를 검색해야합니다.

정확한 경로를 이미 알고 있다면 다음과 같이 스크립트에 하드 코딩 할 수 있습니다.

data['items'][1]['name']

이것들도 작동합니다-

data.items[1].name
data['items'][1].name
data.items[1]['name']

사전에 정확한 이름을 모르거나 사용자가 이름을 제공 한 경우. 그런 다음 데이터 구조를 동적으로 검색해야합니다. 여기에서 일부는 for루프를 사용하여 검색을 수행 할 수 있다고 제안했지만를 사용하여 경로를 탐색하는 매우 간단한 방법이 Array.reduce있습니다.

const data = { code: 42, items: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }] }
const path = [ 'items', '1', 'name']
let result = path.reduce((a,v) => a[v], data)

경로는 다음과 같이 말하는 방법입니다. 먼저 items배열 인 key로 객체를 가져 옵니다. 그런 다음 1-st 요소 (인덱스 배열 0 개)를 가져옵니다 . 마지막 name으로 해당 배열 요소에서 키가있는 객체를 가져 옵니다.이 요소는 문자열 bar입니다.

경로가 매우 긴 String.split경우이 모든 것을 더 쉽게 만드는 데 사용할 수도 있습니다.

'items.1.name'.split('.').reduce((a,v) => a[v], data)

이것은 jQuery 또는 lodash와 같은 타사 라이브러리를 사용하지 않는 단순한 JavaScript입니다.


lodash _get기능을 사용할 수 있습니다 .

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// => 3

https://github.com/s3u/JSONPath (노드 및 브라우저) 라이브러리를 포함하려는 경우 JSONPath를 사용 하는 것이 가장 유연한 솔루션 중 하나입니다.

사용 사례의 경우 json 경로는 다음과 같습니다.

$..items[1].name

그래서:

var secondName = jsonPath.eval(data, "$..items[1].name");

저는 JQuery를 선호합니다. 깨끗하고 읽기 쉽습니다.

 $.each($.parseJSON(data), function (key, value) {
    alert(value.<propertyname>);
});


2017 년 이후에이 질문을 방문하여 기억하기 쉬운 방법 찾고있는 경우를 대비해 JavaScript에서 중첩 된 개체 액세스 에 대한 정교한 블로그 게시물 이 있습니다.

정의되지 않은 오류 의 'foo'속성을 읽을 수 없습니다.

1. Oliver Steele의 중첩 된 개체 액세스 패턴

가장 쉽고 깨끗한 방법은 Oliver Steele의 중첩 된 객체 액세스 패턴을 사용하는 것입니다.

const name = ((user || {}).personalInfo || {}).name;

이 표기법을 사용하면 절대로

정의되지 않은 '이름'속성을 읽을 수 없습니다 .

기본적으로 사용자가 있는지 확인하고 그렇지 않은 경우 즉시 빈 개체를 만듭니다. 이렇게하면 항상 존재하는 객체 또는 빈 객체 에서 다음 레벨 키에 액세스 할 수 있지만 undefined에서는 액세스 할 수 없습니다.

2. Array Reduce를 사용하여 중첩 된 개체에 액세스

중첩 된 배열에 액세스 할 수 있도록 고유 한 배열 reduce util을 작성할 수 있습니다.

const getNestedObject = (nestedObj, pathArr) => {
    return pathArr.reduce((obj, key) =>
        (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}

// pass in your object structure as array elements
const name = getNestedObject(user, ['personalInfo', 'name']);

// to access nested array, just pass in array index as an element the path array.
const city = getNestedObject(user, ['personalInfo', 'addresses', 0, 'city']);
// this will return the city from the first address item.

모든 작업 을 수행 하는 우수한 유형 처리 최소 라이브러리 유형도 있습니다.


var ourStorage = {


"desk":    {
    "drawer": "stapler"
  },
"cabinet": {
    "top drawer": { 
      "folder1": "a file",
      "folder2": "secrets"
    },
    "bottom drawer": "soda"
  }
};
ourStorage.cabinet["top drawer"].folder2; // Outputs -> "secrets"

또는

//parent.subParent.subsubParent["almost there"]["final property"]

기본적으로 그 아래에 펼쳐지는 각 하위 항목 사이에 점을 사용하고 두 문자열로 구성된 개체 이름이있는 경우 [ "obj Name"] 표기법을 사용해야합니다. 그렇지 않으면 점만으로 충분합니다.

출처 : https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-objects

여기에 추가하려면 중첩 배열에 액세스하는 것이 다음과 같이 발생합니다.

var ourPets = [
  {
    animalType: "cat",
    names: [
      "Meowzer",
      "Fluffy",
      "Kit-Cat"
    ]
  },
  {
    animalType: "dog",
    names: [
      "Spot",
      "Bowser",
      "Frankie"
    ]
  }
];
ourPets[0].names[1]; // Outputs "Fluffy"
ourPets[1].names[0]; // Outputs "Spot"

출처 : https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-arrays/

위의 상황을 설명하는 또 다른 유용한 문서 : https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics#Bracket_notation

점 걷기를 통한 속성 액세스 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors#Dot_notation


특정 기준을 충족하는 하나 이상의 객체를 찾고 있다면 query-js를 사용하는 몇 가지 옵션이 있습니다.

//will return all elements with an id larger than 1
data.items.where(function(e){return e.id > 1;});
//will return the first element with an id larger than 1
data.items.first(function(e){return e.id > 1;});
//will return the first element with an id larger than 1 
//or the second argument if non are found
data.items.first(function(e){return e.id > 1;},{id:-1,name:""});

이 또한의 single와는 singleOrDefault그들은 더 같은 일을 first하고 firstOrDefault각각. 유일한 차이점은 이상의 일치 항목이 발견 되면 던질 것이라는 것입니다 .

query-js에 대한 자세한 설명은이 게시물에서 시작할 수 있습니다.


밑줄 js 방법

functional programming내장 객체를 확장하지 않고도 유용한 도우미 를 제공하는 JavaScript 라이브러리입니다 .

해결책:

var data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};

var item = _.findWhere(data.items, {
  id: 2
});
if (!_.isUndefined(item)) {
  console.log('NAME =>', item.name);
}

//using find - 

var item = _.find(data.items, function(item) {
  return item.id === 2;
});

if (!_.isUndefined(item)) {
  console.log('NAME =>', item.name);
}

오래된 질문이지만 아무도 lodash를 언급하지 않았습니다 (단지 밑줄).

프로젝트에서 이미 lodash를 사용하고있는 경우 복잡한 예제에서이를 수행하는 우아한 방법이라고 생각합니다.

선택 1

_.get(response, ['output', 'fund', 'data', '0', 'children', '0', 'group', 'myValue'], '')

다음과 동일 :

옵션 2

response.output.fund.data[0].children[0].group.myValue

첫 번째 옵션과 두 번째 옵션의 차이점은 옵션 1 에서 경로에 누락 된 (정의되지 않은) 속성 중 하나가있는 경우 오류가 발생하지 않으면 세 번째 매개 변수를 반환한다는 것입니다.

배열 필터의 경우 lodash가 _.find()있지만 차라리 일반 filter(). 하지만 여전히 위의 방법 _.get()은 정말 복잡한 데이터로 작업 할 때 매우 유용 하다고 생각합니다 . 나는 과거에 정말 복잡한 API에 직면했고 편리했습니다!

제목이 암시하는 정말 복잡한 데이터를 조작하는 옵션을 찾는 사람에게 유용 할 수 있기를 바랍니다.


질문자는 한 수준의 중첩 객체에만 관심이 있다고 생각하지 않으므로 깊이 중첩 된 json 객체의 노드에 액세스하는 방법을 보여주기 위해 다음 데모를 제시합니다. 좋습니다. ID가 '5'인 노드를 찾아 봅시다.

var data = {
  code: 42,
  items: [{
    id: 1,
    name: 'aaa',
    items: [{
        id: 3,
        name: 'ccc'
      }, {
        id: 4,
        name: 'ddd'
      }]
    }, {
    id: 2,
    name: 'bbb',
    items: [{
        id: 5,
        name: 'eee'
      }, {
        id: 6,
        name: 'fff'
      }]
    }]
};

var jsonloop = new JSONLoop(data, 'id', 'items');

jsonloop.findNodeById(data, 5, function(err, node) {
  if (err) {
    document.write(err);
  } else {
    document.write(JSON.stringify(node, null, 2));
  }
});
<script src="https://rawgit.com/dabeng/JSON-Loop/master/JSONLoop.js"></script>


동적 다중 레벨 객체에 액세스합니다.

var obj = {
  name: "salut",
  subobj: {
    subsubobj: {
      names: "I am sub sub obj"
    }
  }
};

var level = "subobj.subsubobj.names";
level = level.split(".");

var currentObjState = obj;

for (var i = 0; i < level.length; i++) {
  currentObjState = currentObjState[level[i]];
}

console.log(currentObjState);

작업 바이올린 : https://jsfiddle.net/andreitodorut/3mws3kjL/


임의의 JSON 트리를 풀기위한 파이썬적이고 재귀 적이며 기능적인 접근 방식 :

handlers = {
    list:  iterate,
    dict:  delve,
    str:   emit_li,
    float: emit_li,
}

def emit_li(stuff, strong=False):
    emission = '<li><strong>%s</strong></li>' if strong else '<li>%s</li>'
    print(emission % stuff)

def iterate(a_list):
    print('<ul>')
    map(unravel, a_list)
    print('</ul>')

def delve(a_dict):
    print('<ul>')
    for key, value in a_dict.items():
        emit_li(key, strong=True)
        unravel(value)
    print('</ul>')

def unravel(structure):
    h = handlers[type(structure)]
    return h(structure)

unravel(data)

여기서 데이터 는 Python 목록 (JSON 텍스트 문자열에서 구문 분석 됨)입니다.

data = [
    {'data': {'customKey1': 'customValue1',
           'customKey2': {'customSubKey1': {'customSubSubKey1': 'keyvalue'}}},
  'geometry': {'location': {'lat': 37.3860517, 'lng': -122.0838511},
               'viewport': {'northeast': {'lat': 37.4508789,
                                          'lng': -122.0446721},
                            'southwest': {'lat': 37.3567599,
                                          'lng': -122.1178619}}},
  'name': 'Mountain View',
  'scope': 'GOOGLE',
  'types': ['locality', 'political']}
]

jQuery의 grep 함수를 사용하면 배열을 통해 필터링 할 수 있습니다.

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

$.grep(data.items, function(item) {
    if (item.id === 2) {
        console.log(item.id); //console id of item
        console.log(item.name); //console name of item
        console.log(item); //console item object
        return item; //returns item object
    }

});
// Object {id: 2, name: "bar"}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


stringjsonPHP 파일에서 왔지만 여전히 여기에 var. 내 json을 직접 가져 가면 objjson 파일을 다음과 같이 넣는 이유가 표시되지 않습니다.

var obj=JSON.parse(stringjson);그래서 그 후 messageobj를 얻고 경고 상자에 표시 한 다음 datajson 배열을 얻고 하나의 변수에 저장 한 ArrObj다음이와 같은 키 값으로 해당 배열의 첫 번째 객체를 읽습니다.ArrObj[0].id

     var stringjson={
        "success": true,
        "message": "working",
        "data": [{
                  "id": 1,
                  "name": "foo"
         }]
      };

                var obj=JSON.parse(stringjson);
                var key = "message";
                alert(obj[key]);
                var keyobj = "data";
                var ArrObj =obj[keyobj];

                alert(ArrObj[0].id);

동적 접근

아래 deep(data,key)함수에서 임의의 '키'문자열을 사용할 수 있습니다-귀하의 경우 key='items[1].name'( [i]모든 수준에서 배열 표기법 사용할 수 있음 )-키가 유효하지 않으면 undefined가 반환됩니다.

let key = 'items[1].name' // arbitrary deep-key

let data = {
    code: 42,
    items: [
      { id: 1, name: 'foo'}, 
      { id: 2, name: 'bar'},
   ]
};

let deep = (o,k) => {
  return k.split('.').reduce((a,c,i) => {
    let m=c.match(/(.*?)\[(\d*)\]/);
    if(m && a!=null && a[m[1]]!=null) return a[m[1]][+m[2]];
    return a==null ? a: a[c];
  },o)
}

console.log( deep(data,key) );


lodash를 사용하는 것이 좋은 해결책이 될 것입니다

전의:

var object = { 'a': { 'b': { 'c': 3 } } };                                                                                               
_.get(object, 'a.b.c');                                                                                             
// => 3  

참고 URL : https://stackoverflow.com/questions/11922383/how-can-i-access-and-process-nested-objects-arrays-or-json

반응형