1

I have an array of object which inturn has multiple array of object inside, the subGroups can be up to nth level and I want to flatten it to single array of object.

Input

obj = [{ id: a1, name: "apple", subGroups:  [{id: a2, name: "apple-a", subGroups: {id: a3, name: "apple-b", subGroups:  [{id: a4, name: "apple-c", subGroups: {id: a5, name: "apple-d", subGroups:[]}}]}}]}]

Expected output

[{ id: a1, name: "apple"}, {id: a2, name: "apple-a"}, {id: a3, name: "apple-b"}, {id: a4, name: "apple-c"},{id: a5, name: "apple-d"}]

I have used flat map and reduce but I'm only able to flatten upto second level. pls help

const arr = obj.reduce(
      (arr, elem) => [...arr, ...elem.subGroups], []
    )
    console.log(arr)
1
  • 1
    Some of your subgroups are arrays, and some are objects. Is that really how the data is laid out? Commented Oct 21, 2020 at 6:59

3 Answers 3

3

You'll need recursion. I assume here that subGroups is always an array (or undefined/null):

let obj = [{ id: "a1", name: "apple", subGroups:  [{id: "a2", name: "apple-a", subGroups: [{id: "a3", name: "apple-b", subGroups:  [{id: "a4", name: "apple-c", subGroups: [{id: "a5", name: "apple-d", subGroups:[]}]}]}]}]}]

const flatten = (groups) => 
    (groups || []).flatMap(({subGroups, ...o}) => [o, ...flatten(subGroups)]);

console.log(flatten(obj));

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

Comments

2

This can be done recursively as follows.

const input = [{
  id: "a1",
  name: "apple",
  subGroups: [{
    id: "a2",
    name: "apple-a",
    subGroups: [{
      id: "a3",
      name: "apple-b",
      subGroups: [{
        id: "a4",
        name: "apple-c",
        subGroups: [{
          id: "a5",
          name: "apple-d",
          subGroups: []
        }]
      }]
    }]
  }]
}];

function loopValues(val) {
  let q = [];
  val.forEach(elm => {
    if(elm == null) {
      return;
    }
    
    const { subGroups, ...rest } = elm;
    q = [...q, rest, ...loopValues(subGroups)];
  });
  return q;
}

const output = loopValues(input);
console.log(output);

Comments

0
function flatten(array, currentArray) {
  if (!array) return currentArray;

  return array.reduce((acumulatedArray, currentElement) => {
    const { subGroups, ...element } = currentElement;
    return [...acumulatedArray, element, ...flatten(subGroups, [])];
  }, currentArray);
}

// Or width flatMap

function flatten(array, currentArray) {
  if (!array) return currentArray;

  return [...array.flatMap((currentElement) => {
    const { subGroups, ...element } = currentElement;
    return [element, ...flatten(subGroups, [])];
  }), ...currentArray];
}

const res = flatten(
  [
    {
      id: "a1",
      name: "apple",
      subGroups: [
        {
          id: "a2",
          name: "apple-a",
          subGroups: [
            {
              id: "a3",
              name: "apple-b",
              subGroups: [
                {
                  id: "a4",
                  name: "apple-c",
                  subGroups: [{ id: "a5", name: "apple-d", subGroups: [] }],
                },
              ],
            },
          ],
        },
      ],
    },
  ],
  []
);

console.log(res);

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.