I have a nested data structure containing objects and arrays. How to extract information, i.e. access specific or multiple values (or keys)?
For example:
var data = { code: 42, items: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }] };
How to access the name
of the second item in items
?
P粉4765470762023-10-10 16:45:24
You can access it this way
data.items[1].name
or
data["items"][1]["name"]
Both methods are equal.
P粉0020233262023-10-10 13:48:33
JavaScript has only one data type that can contain multiple values: Object. Array is a special form of object.
(Normal) objects have the following form
{key: value, key: value, ...}
The form of the array is
[value, value, ...]
Both arrays and objects expose a key -> value
structure. Keys in arrays must be numbers, while any string can be used as a key in an object. Key-value pairs are also called "properties".
You can use dot notationto access properties
const value = obj.someProperty;
or Bracket notation , if the property name is not a valid JavaScript Identifier name[spec], or the name Is the value of the variable:
// 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];
Therefore, array elements can only be accessed using bracket notation:
const value = arr[5]; // arr.5 would be a syntax error // property name / index as variable const x = 5; const value = arr[x];
JSON is a text representation of data, just like XML, YAML, CSV, etc. To process such data, you first have to convert it to JavaScript data types, namely arrays and objects (how to process these data was just explained). Question Parsing JSON in JavaScript? How to parse JSON is explained in . < /p>
How to access arrays and objects is JavaScript basic knowledge, so it is recommended to read the MDN JavaScript Guide, especially the various parts
A nested data structure is an array or object that refers to other arrays or objects, that is, its value is an array or object. Such structures can be accessed by successive application of dot or bracket notation.
This is an example:
const data = { code: 42, items: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }] };
Suppose we want to access the name
of the second project.
Here's how we do it step by step:
As we can see, data
is an object, so we can access its properties using dot notation. items
The attributes are accessed as follows:
data.items
The value is an array, to access its second element we must use bracket notation:
data.items[1]
The value is an object, and we again use dot notation to access the name
property. So we end up with:
const item_name = data.items[1].name;
Alternatively, we can use bracket notation for any attribute, especially if the name contains characters that make it invalid for dot notation:
const item_name = data['items'][1]['name'];
undefined
messages? Most of the time when you encounter undefined
the object/array simply does not have a property with that name.
const foo = {bar: {baz: 42}}; console.log(foo.baz); // undefined
Use console.log
or console.dir
and check the structure of the object/array. It's possible that the property you're trying to access is actually defined on a nested object/array.
console.log(foo.bar.baz); // 42
If the property name is unknown or we want to access all properties of the object/array element, we can use for...in
[MDN] Loop over objects and for
< em>[MDN] Loop through arrays to iterate over all properties/elements.
Object
To iterate over all properties of data
, we can iterate over objects as follows:
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 }
Depending on where the object comes from (and what you want to do), you may have to test on each iteration whether the property is indeed a property of the object, or an inherited property. You can use Object#hasOwnProperty代码> [MDN]
.
As an alternative to for...in
and hasOwnProperty
, you can use Object.keys
[MDN ] Get attribute name array :
Object.keys(data).forEach(function(prop) { // `prop` is the property name // `data[prop]` is the property value });
Array
To iterate over all elements of data.items
array we use a for
loop:
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`. }
It is also possible to iterate over an array using for...in
, but there are some reasons why this should be avoided: Why use "for(var item in list)" for arrays in JavaScript Considered bad practice? .
As browser support for ECMAScript 5 continues to increase, the array method forEach
[MDN] also becomes an interesting alternative plan:
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) });
In environments that support ES2015 (ES6), you can also use for...of
[MDN] Loops, which work not only with arrays, but with any iterable object:
for (const item of data.items) { // `item` is the array element, **not** the index }
On each iteration, for...of
gives us the next element of the iterable directly, with no "index" to access or use.
In addition to unknown keys, the "depth" of the data structure (i.e. how many nested objects there are) may also be unknown. How you access deeply nested properties often depends on the exact data structure.
But if the data structure contains repeating patterns, such as the representation of a binary tree, the solution usually involves recursion < em>[Wikipedia] Access every level of the data structure.
The following is an example of obtaining the first leaf node of a binary tree:
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);