Home  >  Q&A  >  body text

How to access and handle nested objects, arrays, or JSON?

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粉864872812P粉864872812397 days ago609

reply all(2)I'll reply

  • P粉476547076

    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.

    reply
    0
  • P粉002023326

    P粉0020233262023-10-10 13:48:33

    Preliminary knowledge

    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];

    Wait...what about JSON?

    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>

    Further reading material

    How to access arrays and objects is JavaScript basic knowledge, so it is recommended to read the MDN JavaScript Guide, especially the various parts



    Access nested data structures

    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'];

    I'm trying to access a property but I only get 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

    What if the property names are dynamic and I don't know them beforehand?

    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.


    What if I don't know the "depth" of the data structure?

    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);

    reply
    0
  • Cancelreply