질문 : 중첩 된 객체, 배열 또는 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
'프로그래밍 언어 > HTML,CSS,JS' 카테고리의 다른 글
컨트롤러를 두 번 실행하는 AngularJS와의 전투 (0) | 2021.07.01 |
---|---|
Node.js 프로젝트 용 package.json 파일을 자동으로 빌드하는 방법 (0) | 2021.06.30 |
JavaScript 배열을 무작위로 섞는 방법 (0) | 2021.06.29 |
HTML을 사용하여 문서의 모든 페이지에 머리글과 바닥글을 출력하는 방법 (0) | 2021.06.29 |
angular HTML 바인딩 (0) | 2021.06.29 |