3

I have the following array of objects.. How can I flatten a multi-dimensional array of objects into a single dimensional array of objects?

[{
    "name":"Locations",
    "children":[
        {
            "name":"U.S."
        },
        {
            "name":"Canada"
        },
        {
            "name":"London"
        }
    ]
},{
    "name":"Benefits",
    "children":[
        {
            "name":"U.S. Benefits",

            "children":[
                {
                    "name":"U.S. Benefits at a Glance"
                },
                {
                    "name":"U.S. Holiday Calendar"
                }
            ]
        },
        {
            "name":"London Benefits",
            "children":[
                {
                    "name":"London Benefits at a Glance"
                },
                {
                    "name":"London Holiday Calendar"
                }
            ]
        },
        {
            "name":"India Benefits",
            "children":[
                {
                    "name":"India Benefits at a Glance"
                },
                {
                    "name":"India Holiday Calendar"
                }
            ]
        }
    ]
}]

I need all the children to be in the same level as their parents in a single dimensional array.Any help will be appreciated.

2
  • I'd create an empty array to collate the final list. I'd then write a recursive algorithm that does array.splice to insert all the children into the final list as it descends, and iterates the children deleting any 'children' properties from the node as it unwinds. Commented May 10, 2018 at 17:55
  • 3
    What does your EXPECTED output look like? Commented May 10, 2018 at 17:56

3 Answers 3

9

You can do this without lodash with reduce and spread syntax. You just need to use recursion for children.

const data = [{"name":"Locations","children":[{"name":"U.S."},{"name":"Canada"},{"name":"London"}]},{"name":"Benefits","children":[{"name":"U.S. Benefits","children":[{"name":"U.S. Benefits at a Glance"},{"name":"U.S. Holiday Calendar"}]},{"name":"London Benefits","children":[{"name":"London Benefits at a Glance"},{"name":"London Holiday Calendar"}]},{"name":"India Benefits","children":[{"name":"India Benefits at a Glance"},{"name":"India Holiday Calendar"}]}]}]

const flatten = data => {
  return data.reduce((r, { children, ...rest}) => {
    r.push(rest);
    if (children) r.push(...flatten(children));
    return r;
  }, [])
}

console.log(flatten(data))

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

Comments

3

Modified answer of @nenad-vracar to more reusable style:

const mock = [{"name":"Locations","children":[{"name":"U.S."},{"name":"Canada"},{"name":"London"}]},{"name":"Benefits","children":[{"name":"U.S. Benefits","children":[{"name":"U.S. Benefits at a Glance"},{"name":"U.S. Holiday Calendar"}]},{"name":"London Benefits","children":[{"name":"London Benefits at a Glance"},{"name":"London Holiday Calendar"}]},{"name":"India Benefits","children":[{"name":"India Benefits at a Glance"},{"name":"India Holiday Calendar"}]}]}];

const flatDeepByKey = (data, key) => {
  return data.reduce((prev, el) => {
    prev.push(el);
    if (el[key]) {
      prev.push(...flatDeepByKey(el[key], key))
    };
    return prev;
  }, [])
};

console.log(flatDeepByKey(mock, 'children'));

Comments

1

You can perform a recursive loop-through and append to a running list by using a helper-function.

Note: If you want to remove the "root" dummy-node, just slice(1) the array.

var flattened = flattenTree({
  "name" : "root",            // Need a root entry, because the data is an array
  "children" : getData()      // Grab the data at the bottom
}, {
  nameKey : 'name',           // The name key; configurable option
  childrenKey : 'children'    // The children key; configurable option
});

console.log(flattened);       // Flattened data printed to the console

function flattenTree(tree, options) {
  options = options || {};
  var nameKey = options.nameKey || 'name';
  var childrenKey = options.childrenKey || 'children'
  var resultList = [];
  flattenTreeRecurse(tree, resultList, nameKey, childrenKey);
  return resultList;
}

/** @private -- Recursive inner-call */
function flattenTreeRecurse(tree, list, nameKey, childrenKey) {
  var entry = {};
  entry[nameKey] = tree[nameKey];
  list.push(entry);
  if (tree[childrenKey] && tree[childrenKey].length > 0) {
    tree[childrenKey].forEach(child => flattenTreeRecurse(child, list, nameKey, childrenKey));
  }
}

function getData() {
  return [{
    "name": "Locations",
    "children": [{
      "name": "U.S."
    }, {
      "name": "Canada"
    }, {
      "name": "London"
    }]
  }, {
    "name": "Benefits",
    "children": [{
        "name": "U.S. Benefits",

        "children": [{
          "name": "U.S. Benefits at a Glance"
        }, {
          "name": "U.S. Holiday Calendar"
        }]
      },
      {
        "name": "London Benefits",
        "children": [{
          "name": "London Benefits at a Glance"
        }, {
          "name": "London Holiday Calendar"
        }]
      },
      {
        "name": "India Benefits",
        "children": [{
          "name": "India Benefits at a Glance"
        }, {
          "name": "India Holiday Calendar"
        }]
      }
    ]
  }];
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

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.