0

I have incoming data in this format:

const worldMap = [
  {
    "name": "Germany",
    "parentId": null,
    "type": "Country",
    "value": "country:unique:key:1234",
    "id": "1",
  },
  {
    "name": "North Rhine",
    "parentId": "1",
    "type": "State",
    "value": "state:unique:key:1234",
    "id": "2",
  },
  {
    "name": "Berlin",
    "parentId": "1",
    "type": "State",
    "value": "state:unique:key:1234",
    "id": "3",
  },  
  {
    "name": "Dusseldorf",
    "parentId": "2",
    "type": "city",
    "value": "city:unique:key:1234",
    "id": "4",
  },
   {
    "name": "India",
    "parentId": null,
    "type": "Country",
    "value": "country:unique:key:1234",
    "id": "5",
  }, 
];

I want the output to be something like this:

[
   {
   label: "Germany",
   value: "country:unique:key:1234",
   subs: [
    {
        label: "North Rhine",
        value: "state:unique:key:1234",
        subs: [
            {
                label: "Dusseldorf",
                value: "city:unique:key:1234",
            }
        ]
    },
    {
       label: "Berlin",
       value: "state:unique:key:1234",
    }
   ]
   }
   ,
   {
       "label": "India",
       "value": "country:unique:key:1234"
   }
]

Basically, it is a three dimensional array with first level being the Countrie, second States and third Cities. I have tried the following code:

let tempCountries = [];

worldMap.map((world) => {
  if (world.parentId == null && world.type == "Country") {
    tempCountries.push({label: world.name, value: world.value, id: world.id});
  }
});

console.log("=== countries ===", tempCountries);

tempCountries.map((tempCountry) => {
  const states = worldMap.find((x) => x.parentId == tempCountry.id);
  console.log("=== states ===", states);
  if (states !== undefined) {
    
  }
});

In the first loop I got all the values for the countries. Next I am trying to append states and cities to the original countries, I got from the first loop. But I am not able to do so. The code should be verbose with minimum number of loops. Could anyone please help achieve this ?

Thanks

Ashy Ashcsi
  • 1,529
  • 7
  • 22
  • 54
  • If you're not interested in the return value of `.map()` then `.map()` is the wrong tool – Andreas Oct 30 '20 at 12:36
  • 1
    _"...with minimum number of loops..."_ - Why this restriction? If a more verbose or readable version requires one more loop than go with it. Readability >> anything else – Andreas Oct 30 '20 at 12:38

1 Answers1

0

You could take a single loop and store all relations between child/parents and parents/childs.

const
    data = [{ name: "Germany", parentId: null, type: "Country", value: "country:unique:key:1234", id: "1" }, { name: "North Rhine", parentId: "1", type: "State", value: "state:unique:key:1234", id: "2" }, { name: "Berlin", parentId: "1", type: "State", value: "state:unique:key:1234", id: "3" }, { name: "Dusseldorf", parentId: "2", type: "city", value: "city:unique:key:1234", id: "4" }, { name: "India", parentId: null, type: "Country", value: "country:unique:key:1234", id: "5" }],
    tree = ((data, root) => {
        var t = {};
        data.forEach(({ id, parentId, name: label, value }) => {
            Object.assign(t[id] = t[id] || {}, { label, value });
            t[parentId] = t[parentId] || {};
            (t[parentId].subs = t[parentId].subs || []).push(t[id]);
        });
        return t[root].subs;
    })(data, null);

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392