6

Trying to turn an array of objects into a nested object. Is there a good method for this? and how do I make it depending on the array length?

Working but is not universal: https://codesandbox.io/s/thirsty-roentgen-3mdcjv?file=/src/App.js

What I have:

sorting: [
    {
    "id": "HighestDegree",
    "options": [
            "HighSchool",
            "Undergraduate",
            "Bachelor",
            "Master",
            "Doctor"
        ]
    },
    {
    "id": "gender",
    "options": [
            "male",
            "female"
        ]
    }
]

What I want:

value: {
    "Region": "Oklahoma",
    "HighestDegree": {
        "HighSchool": {
            "male": null,
            "female":null
        },
        "Undergraduate":{
            "male": null,
            "female":null
        }
    //and so on...
    }
}

The code beneath works but is hardcoded for only two different options. I want it to be able to nest the length of the array. So lets say another object was age it would be {"HighSchool":{male:{"<25":null,"25-35":null}}} etc..

function testSortingArray() {
    let sorting = [
      {
        id: "HighestDegree",
        options: ["HighSchool", "Undergraduate", "Bachelor", "Master", "Doctor"]
      },
      {
        id: "gender",
        options: ["male", "female"]
      }
    ];
    let GoalArray = {};
    if (sorting.length > 0) {
      sorting[0].options.map((firstArray) => {
        let currObject = {};
        sorting[1].options.map((secondOption) => {
          currObject[secondOption] = null;
        });
        GoalArray[firstArray] = currObject;
      });
    }
    return GoalArray;
  }
  console.log(testSortingArray());

1 Answer 1

5

You can do it with a recursive function.

The function below reduces every options array to an object, and then continues populating that object if there are rest elements left from the original sorting array.

const fn = ([{ options }, ...rest]) => options.reduce((a, v) => ({
  ...a,
  [v]: rest.length ? fn(rest): null
}), {});
const result = fn(sorting);

Besides the reduce() method, the code above makes use of object and array destructuring and spread syntax.


Complete snippet:

const sorting = [{
  "id": "HighestDegree",
  "options": [
    "HighSchool",
    "Undergraduate",
    "Bachelor",
    "Master",
    "Doctor"
  ]
}, {
  "id": "gender",
  "options": [
    "male",
    "female"
  ]
}, {
  "id": "age",
  "options": [
    "<25",
    "25-35"
  ]
}];

const fn = ([{ options }, ...rest]) => options.reduce((a, v) => ({
  ...a,
  [v]: rest.length ? fn(rest): null
}), {});
const result = fn(sorting);

console.log(result);

Sign up to request clarification or add additional context in comments.

4 Comments

Some explanation of the code would not be remiss as always.
Well, we get hundreds of questions a day about what syntax like [{ options }, ...rest] means, even before the currying.
@HereticMonkey Fair enough. Added some links for the more salient parts.
Beautiful and clean solution, great destructuring and usage of rest params length as a base case for recursion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.