skip to Main Content

I’m working in Typescript.

If I have an object about which I know nothing, how could I obtain
from that object a list of all the fields which have the name of, say,
"speed". (Clearly the answer would be null if there were no such entries).

I could JSON.stringify and write my own parsing, but was wondering if there was another way.

So, for example, my object might be:

MyObject = {AnEntry:{"speed":"5", "somthingElse":6},
AnotherEntry:{"somethingElse":"3"},
YetAnother:true,
AndMore:{"speed":"eleven"},
Finally:{"more":7,nested:{"notHere":7, "speed":"5"}}};

So, in this case, I would like query MyObject and return [5,"eleven"]

I’ve EDITED: Add = sign and updated object to show that I want to be able to cope with possibly nested objects.

3

Answers


  1. After your Edit

    To get nested prop "speed" values, use a recursive function like:

    const MyObject = {
      AnEntry:{"speed":"5", "somthingElse":6},
      AnotherEntry:{"somethingElse":"3"},
      YetAnother:true,
      AndMore:{"speed":"eleven"},
      Finally:{"more":7, nested:{"notHere":7, "speed":"5"}}
    };
    
    const getValues = (obj, prop) => Object.entries(obj).reduce((a, [k, v]) => {
      if (typeof v === "object") a.push(...getValues(v, prop));
      else if (k === prop) a.push(v);
      return a;
    }, []);
    
    
    const res = getValues(MyObject, "speed");
    console.log(res);

    to get a unique set of values, reduce into a new Set:

    const MyObject = {
      AnEntry:{"speed":"5", "somthingElse":6},
      AnotherEntry:{"somethingElse":"3"},
      YetAnother:true,
      AndMore:{"speed":"eleven"},
      Finally:{"more":7, nested:{"notHere":7, "speed":"5"}}
    };
    
    const getValues = (obj, prop) => [...Object.entries(obj).reduce((a, [k, v]) => {
      if (typeof v === "object" && Object.hasOwn(v, prop)) a.add(...getValues(v, prop));
      else if (k === prop) a.add(v);
      return a;
    }, new Set)];
    
    
    const res = getValues(MyObject, "speed");
    console.log(res);

    To get an array of the filtered fields where speed property (key) exists you could use:

    const MyObject = {
      AnEntry: {"speed": "5","somthingElse": 6},
      AnotherEntry: {"somethingElse": "3"},
      YetAnother: true,
      AndMore: {"speed": "eleven"},
      Finally: {"speed": "5"}
    };
    
    const fields = Object.values(MyObject).filter((ob) => Object.hasOwn(ob, "speed"));
    console.log(fields);

    To get only an Array of the values use:

    const MyObject = {
      AnEntry: {"speed": "5","somthingElse": 6},
      AnotherEntry: {"somethingElse": "3"},
      YetAnother: true,
      AndMore: {"speed": "eleven"},
      Finally: {"speed": "5"}
    };
    
    const values = Object.values(MyObject).reduce((a, ob) => (Object.hasOwn(ob, "speed") && a.push(ob.speed), a), []);
    console.log(values);

    To get only unique values, use new Set()

    const MyObject = {
      AnEntry: {"speed": "5","somthingElse": 6},
      AnotherEntry: {"somethingElse": "3"},
      YetAnother: true,
      AndMore: {"speed": "eleven"},
      Finally: {"speed": "5"}
    };
    
    const valuesUnique = [...Object.values(MyObject).reduce((a, ob) => (Object.hasOwn(ob, "speed") && a.add(ob.speed), a), new Set())];
    console.log(valuesUnique);

    Docs:

    Login or Signup to reply.
  2. Assuming you know nothing about the object, the "speed" attributes might be nested at multiple depths within your object. You can use recursion to traverse the tree of nested children to reach all of them.

    const MyObject = {
      speed: "1",
      AnEntry: {"speed": "2","somthingElse": 6},
      AnotherEntry: {"somethingElse": {"speed":"3"}},
      YetAnother: true,
      AndMore: {"speed": "four"},
      Finally: {"speed": 5}
    };
    
    let speeds=[];
    function buildSpeeds(speeds, obj) {
        for (key of Object.keys(obj)) {
            if (!Object.hasOwn(obj, key)) continue;
            let value=obj[key];
            if (key=="speed") speeds.push(value);
            if (value!==null && typeof value === 'object' && !Array.isArray(value)) {
                buildSpeeds(speeds, value);
            }
        }
    }
    buildSpeeds(speeds, MyObject);
    console.log(JSON.stringify(speeds));
    

    Result:

    ["1","2","3","four",5]
    
    Login or Signup to reply.
  3. const data =  {
      AnEntry: { speed: "5", somthingElse: 6 },
      AnotherEntry: { somethingElse: "3" },
      YetAnother: true,
      AndMore: {
        OtherInfo: { speed: "eleven", method: "dsf" },
        detailInfo: {
          infoTest: {
            speed: 123123,
            k: "fff",
          },
        },
      },
      Finally: { speed: 0 },
    }
    
    const getField = (object = {}, field = "") => {
      let keys = Object.keys(object);
      keys = keys.length == 1 && object[keys[0]] == object ? [] : keys;
      let list = [];
      if (keys.indexOf(field) != -1) {
        list.push(object[field]);
        object[field] = {};
      }
      if (keys.length != 0)
        list = [
          ...list,
          ...keys
            .map((key) => [...getField(object[key], field)])
            .reduce((acc, cur) => [...acc, ...cur]),
        ];
      return list.filter(
        (item) => !(typeof item == "object" && item.length == 0)
      );
    };
    
      getField(data, "speed") // ['5', 'eleven', 123123, 0]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search