Search key and return value in nested object

前端 未结 4 868
盖世英雄少女心
盖世英雄少女心 2021-01-28 17:02

Lets say my object looks like the below. Its a mix of different arrays and parents, no hierarchical order. e.g.

\"person\": {
\"id\": 12345,
\"name\": \"John Doe         


        
4条回答
  •  死守一世寂寞
    2021-01-28 17:24

    I generalized it a bit with code shamelessly stolen from my own lib: goodcore

    I chose a recursice approach since I believe the code is much easier to analyze although it has more code.

    let obj = {
        "id": 12345,
        "name": "John Doe",
        "emergencyContacts": [{
            "name": "Jane Doe",
            "phone": "888-555-1212",
            "relationship": "spouse",
            "moreDetails": {
              "id": 12345,
              "phones": {},
              "home": "800-123-4567",
              "mobile": "877-123-1234"
            }
          },
          {
            "name": "Justin Doe",
            "phone": "877-123-1212",
            "relationship": "parent",
            "mobile": "877-123-1234"
          }
        ],
        "workContacts": [{
            "name": "Jane Doe",
            "phone": "888-555-1212",
            "relationship": "spouse",
            "moreworkDetails": {
              "id": 12345,
              "phones": {},
              "home": "800-123-4567",
              "mobile": "877-123-1236"
            }
          },
          {
            "name": "Justin Doe",
            "phone": "877-123-1212",
            "relationship": "parent",
            "mobile": "877-123-1235"
          }
        ]
      };
    
    function isObject(it) {
        return it !== null && typeof it === "object";
    }
    function isArray(it) {
        return Array.isArray ? Array.isArray(it) : Object.prototype.toString.call(it) === "[object Array]";
    }
    function forEach(target, fn) {
        if(isArray(target)) {
            target.forEach(fn);
        } else {
            Object.entries(target).forEach(([key, value]) => fn(value, key));
        }
    }
    function objReduce(obj, fn, acc) {
        let a = acc;
        forEach(obj, (value, key) => {
            if(isObject(value) || isArray(value)) {
                a = objReduce(value, fn, a);
            } 
            a = fn(a, value, key);
        });
        return a;
    }
    
    objReduce(obj, (acc, cur, key) => {
        if(key === "mobile") {
            acc.push(cur);
        }
        return acc;
    }, []);
    

    Basically what it does is that it creats an object reduce function that loops over all properties and runs an accumulator function on it much like Array.prototype.reduce does for arrays. It needed a bit of code since it handles arrays and objects arbitrarily.

提交回复
热议问题