프로그래밍 언어/HTML,CSS,JS

중첩 된 객체, 배열 또는 JSON에 액세스하고 처리하는 방법

Rateye 2021. 6. 29. 10:12
728x90
반응형

 

질문 : 중첩 된 객체, 배열 또는 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은 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 를 얻을 때 대부분의 경우 객체 / 배열에는 해당 이름의 속성이 없습니다.

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...in with hasOwnProperty 대신 Object.keys [MDN] 을 사용 하여 속성 이름 배열 을 가져올 수 있습니다.

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)'가 배열을 사용하여 JavaScript에서 나쁜 습관으로 간주됩니까? .

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

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__ 세 가지 속성이 있음을 알 수 있습니다. 후자는 객체의 프로토 타입 체인에 사용되는 내부 속성입니다. 하지만 프로토 타입 체인과 상속은이 답변의 범위를 벗어납니다.

출처 : https://stackoverflow.com/questions/11922383/how-can-i-access-and-process-nested-objects-arrays-or-json
728x90
반응형