Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Iterate over JSON object, find key and value, return an object where it's found

I have a complex JSON that has nested objects and arrays.
E.g.

[
  {
    "Id": 1,
    "Name": "Foo",
    "Cached": true,
    "Accessories": [2, 4, 16],
    "Promo": [{"Type": 1, "Date": "null", "Priority": 1}, ...],
    ...
  },
  {
    "Id": 2,
    "Name": "Bar",
    "Cached": false,
    "Accessories": [16, 32, 64],
    "Promo": [{"Type": 2, "Date": "null", "Priority": 2}, ...],
    ...
  },
  ...
]

I want to iterate over each key (including nested objects and arrays) with JavaScript (using built-in features without 3rd-party libs), find the matching key and value (let’s say "Name" = "Bar"), and return the object that contains the matched result.

Assuming the key-value pair I’m looking for is unique, so returning the first match is fine.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I tried several different recursive functions, but couldn’t achieve the desired result.
The closest one was this https://medium.com/@alaneicker/how-to-process-json-data-with-recursion-dc530dd3db09
It iterates the entire structure properly but I can’t make it return the matched object.

upd. Best effort code (still doesn’t work as expected)

function loopThroughJSON(obj, searchKey, searchValue) {
  if (typeof obj === 'string') {
    obj = JSON.parse(obj);
  }
  
  for (var key in obj) {
    if (typeof obj[key] === 'object') {
      if (Array.isArray(obj[key])) {
        for (var i = 0; i < obj[key].length; i++) {
          return loopThroughJSON(obj[key][i], searchKey, searchValue);
        }
      } else {
          return loopThroughJSON(obj[key], searchKey, searchValue);
      }
    } else {
      if ((key === searchKey) && (obj[key] === searchValue)) {
        return obj;
      }
    }
  }

  return null;
}

>Solution :

The problem with your code is you’re returning the prematured result inside the loop i.e. if the first item in the loop does not meet the condition, the function will return without checking the remaining items. A sample working recursive function would look something like:

function findObjectWithKeyAndVal(obj, key, value) {
 // checking array
  if (Array.isArray(obj)) {
    for (let item of obj) {
      const result = findObjectWithKeyAndVal(item, key, value);
      if (result) {
        return result;
      }
    }
  } else if (typeof obj === 'object') {
    // base case
    if (obj[key] === value) {
      return obj;
    }

    for (let item in obj) {
      const result = findObjectWithKeyAndVal(obj[item], key, value);
      if (result) {
        return result;
      }
    }
  }
  return null;
}

const jsonData = [
  {
    "Id": 1,
    "Name": "Foo",
    "Cached": true,
    "Accessories": [2, 4, 16],
    "Promo": [{"Type": 1, "Date": "null", "Priority": 1}],
  },
  {
    "Id": 2,
    "Name": "Bar",
    "Cached": false,
    "Accessories": [16, 32, 64],
    "Promo": [{"Type": 2, "Date": "null", "Priority": 2}],
  },
];

const key = 'Name';
const value = 'Bar';

const result = findObjectWithKeyAndVal(jsonData, key, value);
console.log(result);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading