0

I have a JS array (shown 4 examples actual has 66 )

[["A","Example1"],["A","Example2"],["B","Example3"],["B","Example4"]]

that I am trying to get into an object for a multi select drop down menu:

var opt = [{
label: 'A', children:[
        {"label":"Example1","value":"Example1","selected":"TRUE"},
        {"label":"Example2","value":"Example2","selected":"TRUE"} 
      ]
},

{
label: 'B', children:[
  {"label":"Example3","value":"Example3","selected":"TRUE"},
  {"label":"Example4","value":"Example4","selected":"TRUE"}
  ]
}
]

Is there a easy way to do this ?

4
  • 2
    It can be done with a single .reduce(), though "easy" is certainly relative, and as a result the answer to your question is a subjective "yes" or "no". Perhaps you could share your attempts or a specific difficulty you're encountering, so that we can help out as opposed to writing the code for for you :) Commented Dec 11, 2019 at 21:06
  • (For what it's worth I've removed all references to JSON in your question as well, including the title and tags, as it doesn't seem related.) Commented Dec 11, 2019 at 21:13
  • I'm currently trying to figure out a way to use For loops. starting with identifying the unique first value of the embedded arrays then loop through the arrays finding which match the list of unique values. Commented Dec 11, 2019 at 21:18
  • I think, instead of Array of objects, ES6 maps would make things easier. Commented Dec 11, 2019 at 21:20

3 Answers 3

1

Updated: Using reduce() and filter() to get expected results.

const result = [['A', 'Example1'], ['A', 'Example2'], ['B', 'Example3'], ['B', 'Example4']].reduce((acc, cur) => {
  const objFromAccumulator = acc.filter((row) => row.label === cur[0]);
  const newChild = {label: cur[1], value: cur[1], selected: 'TRUE'};
  if (objFromAccumulator.length) {
    objFromAccumulator[0].children.push(newChild);
  } else {
    acc.push({label: cur[0], children: [newChild]});
  }
  return acc;
}, []);

console.log(result);

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

3 Comments

this is great but backwards from what I'm trying to achieve. I'm wanting to go from the array of array to the 'label' format.
@TygerGuzman Isn't the result an array of array to the label format from my answer? [["A", "Example1"], ["A", "Example2"], ["B", "Example3"], ["B", "Example4"]]
I'm trying to go from [["A","Example1"],["A","Example2"],["B","Example3"],["B","Example4"]] to [{ label: 'A', children:[ {"label":"Example1","value":"Example1","selected":"TRUE"}, {"label":"Example2","value":"Example2","selected":"TRUE"} ] }, { label: 'B', children:[ {"label":"Example3","value":"Example3","selected":"TRUE"}, {"label":"Example4","value":"Example4","selected":"TRUE"} ] } ]
1

Something like this should work:

const raw = [["A","Example1"],["A","Example2"],["B","Example3"],["B","Example4"]];

const seen = new Map();
const processed = raw.reduce((arr, [key, label]) => {
    if (!seen.has(key)) {
        const item = {
            label: key,
            children: []
        };
        seen.set(key, item);
        arr.push(item);
    }
    seen.get(key).children.push({
        label,
        value: label,
        selected: "TRUE"
    })
    return arr;
}, []);
console.log(processed);

Comments

1

Here's a rather efficient and concise take on the problem using an object as a map:

const data = [["A","Example1"],["A","Example2"],["B","Example3"],["B","Example4"]];

const opt = data.reduce((results,[key,val]) => {
  if(!results[0][key]) //first element of results is lookup map of other elements
    results.push(results[0][key] = { label: key, children: [] });
  results[0][key].children.push({ label: val, value: val, selected:"TRUE" });
  return results;
}, [{}]).slice(1); //slice off map as it's no longer needed

console.log(opt);

Comments

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.