1

I have a JSON object that I'm only interested in one of the key "codes" and its values. I would like to run a loop to get those values for every region and country and city and store them in an array.

{
"region":{
    "America":{
        "countries":{
            "US":{
                "cities":{
                    "NY":{
                        "codes":["142","2243","312","4123","5132"]
                    },
                    "LA":{
                        "codes":["1465","2465","3453","4132","542"]
                    }
                }
            },
            "CANADA":{
                "cities":{
                    "TORNTO":{
                        "codes":["1465","2465","3453","4132","542"]
                    }
                }

            }
        }
    },
    "ASIA":{
        "countries":{
            "India":{
                "cities":{
                    "Delhi ":{
                        "codes":["142","2243","312","4123","5132"]
                    },
                    "Calcutta":{
                        "codes":["1465","2465","3453","4132","542"]
                    }
                }
            },
            "CHINA":{
                "cities":{
                    "HONKKON":{
                        "codes":["1465","2465","3453","4132","542"]
                    }
                }

            }
        }
    }

}

}

what I have done

getCodes(regions){
let ccode = [];
for (let key of Object.values(region)) {
    for (let temp of Object.values(key)) {
        for (let ctemp of Object.values(temp)) {
            for (btemp of Object.values(ctemp)) {
                for (let bbtemp of Object.values(btemp)) {
                    ccode.push(...bbtemp["code"])
}
            }
        }
    }

}

}

However, all my interest is to collect the codes values in every single region and put them together in a list. any practical way?

2 Answers2

2

You can go with a recursive approach like this:

const extractCodes = obj => {
  let codes = [];
  for (const key in obj) {
    if (key === 'codes') return [...obj[key]];
    else {
      codes = [...codes, ...extractCodes(obj[key])];
    }
  }
  return codes;
};

const region = {
  America: {
    countries: {
      US: {
        cities: {
          NY: {
            codes: ['142', '2243', '312', '4123', '5132']
          },
          LA: {
            codes: ['1465', '2465', '3453', '4132', '542']
          }
        }
      },
      CANADA: {
        cities: {
          TORNTO: {
            codes: ['1465', '2465', '3453', '4132', '542']
          }
        }
      }
    }
  },
  ASIA: {
    countries: {
      India: {
        cities: {
          'Delhi ': {
            codes: ['142', '2243', '312', '4123', '5132']
          },
          Calcutta: {
            codes: ['1465', '2465', '3453', '4132', '542']
          }
        }
      },
      CHINA: {
        cities: {
          HONKKON: {
            codes: ['1465', '2465', '3453', '4132', '542']
          }
        }
      }
    }
  }
};

console.log(extractCodes(region));

In case you want to extract unique values only (codes without repetition), You can use Set:

const extractCodes = obj => {
  let codes = [];
  for (const key in obj) {
    if (key === 'codes') return [...obj[key]];
    else {
      codes = [...new Set([...codes, ...extractCodes(obj[key])])];
    }
  }
  return codes;
};

const region = {
  America: {
    countries: {
      US: {
        cities: {
          NY: {
            codes: ['142', '2243', '312', '4123', '5132']
          },
          LA: {
            codes: ['1465', '2465', '3453', '4132', '542']
          }
        }
      },
      CANADA: {
        cities: {
          TORNTO: {
            codes: ['1465', '2465', '3453', '4132', '542']
          }
        }
      }
    }
  },
  ASIA: {
    countries: {
      India: {
        cities: {
          'Delhi ': {
            codes: ['142', '2243', '312', '4123', '5132']
          },
          Calcutta: {
            codes: ['1465', '2465', '3453', '4132', '542']
          }
        }
      },
      CHINA: {
        cities: {
          HONKKON: {
            codes: ['1465', '2465', '3453', '4132', '542']
          }
        }
      }
    }
  }
};

console.log(extractCodes(region));
Amr Salama
  • 802
  • 1
  • 7
  • 19
  • I'm trying to implement the method, but it is not taking the const const extractCodes = obj => { let codes = []; for (const key in obj) { if (key === 'codes') return [...obj[key]]; else { codes = [...new Set([...codes, ...extractCodes(obj[key])])]; } } return codes; }; is this a type script? if yes, where should implement this? – Anmar Al Shammari Feb 07 '20 at 21:52
  • 1
    It's javascript, which could be used as typescript as well. You can use it as part of controller, or service or even in utils file. it depends on project structure. – Amr Salama Feb 07 '20 at 21:57
  • Can you reform it in the same format I did to obe readable? @amr salama – Anmar Al Shammari Feb 07 '20 at 21:58
  • it says "a class member can not have the const keyword. extractCoodes has a red underlined. – Anmar Al Shammari Feb 07 '20 at 22:00
  • just update `const extractCodes = obj => {` to `extractCodes (obj) {` – Amr Salama Feb 07 '20 at 22:02
  • i have another error in [...new Set([...codes, ...extractCodes(obj[key])])]; } } type ''set – Anmar Al Shammari Feb 07 '20 at 22:08
  • Try something like: `codes = [...(new Set([...codes, ...extractCodes(obj[key])]) || [])];` – Amr Salama Feb 07 '20 at 22:13
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/207440/discussion-between-amr-salama-and-anmar-al-shammari). – Amr Salama Feb 07 '20 at 22:32
0

This is kind of an oldschool approach, but it will work in every browser:

var json = { ... };

function getCodes(obj) {
  var codes = [];
  for (var p in obj) {
    if (obj.hasOwnProperty(p)) {
      if (p === "codes") {
        codes = codes.concat(obj[p]);
      } else if (typeof obj[p] === "object") {
        codes = codes.concat(getCodes(obj[p]));
      }
    }
  }
  return codes;
}

var codes = getCodes(json); // ["142", "2243", "312", "4123", ...]
Đinh Carabus
  • 3,403
  • 4
  • 22
  • 44