1

I have an array of classes:

const transferClasses = [
  {
    id: "c5d91430-aaab-ed11-8daf-85953743f5cc",
    name: "Class1",
    isTransfer: false,
    children: [],
  },
  {
    id: "775cb75d-aaab-ed11-8daf-85953743f5cc",
    name: "Class2",
    isTransfer: false,
    children: [
      {
        id: "89134f56-3ef6-ed11-8daf-85953743f5cc",
        name: "Class2-1",
        isTransfer: false,
        children: [],
      },
      {
        id: "89134f56-3ef6-ed11-8daf-85953743f4cc",
        name: "Class2-2",
        isTransfer: false,
        children: [
          {
            id: "89134f56-3ef6-ed11-8daf-85953743f4de",
            name: "Class2-2-1",
            isTransfer: false,
            children: [],
          },
          {
            id: "89134f56-3ef6-ed11-8daf-85953743f1ce",
            name: "Class2-2-2",
            isTransfer: false,
            children: [],
          },
        ],
      },
    ],
  },
];

I need to iterate over an array and turn it into a flat list. For expample:

const flatList = [
  {
    id: "c5d91430-aaab-ed11-8daf-85953743f5cc",
    name: "Class1",
    isTransfer: false,
    childrenId: null,
    parentId: null,
  },
  {
    id: "775cb75d-aaab-ed11-8daf-85953743f5cc",
    name: "Class2",
    isTransfer: false,
    childrenId: [
      "89134f56-3ef6-ed11-8daf-85953743f5cc",
      "89134f56-3ef6-ed11-8daf-85953743f4cc",
    ],
    parentId: null,
  },
  {
    id: "89134f56-3ef6-ed11-8daf-85953743f5cc",
    name: "Class2-1",
    isTransfer: false,
    childrenId: [],
    parentId: ["775cb75d-aaab-ed11-8daf-85953743f5cc"],
  },
  {
    id: "89134f56-3ef6-ed11-8daf-85953743f5cc",
    name: "Class2-2",
    isTransfer: false,
    childrenId: [
      "89134f56-3ef6-ed11-8daf-85953743f4de",
      "89134f56-3ef6-ed11-8daf-85953743f1ce",
    ],
    parentId: ["775cb75d-aaab-ed11-8daf-85953743f5cc"],
  },
  {
    id: "89134f56-3ef6-ed11-8daf-85953743f4de",
    name: "Class2-2-1",
    isTransfer: false,
    childrenId: [],
    parentId: ["89134f56-3ef6-ed11-8daf-85953743f5cc"],
  },
  {
    id: "89134f56-3ef6-ed11-8daf-85953743f1ce",
    name: "Class2-2-2",
    isTransfer: false,
    childrenId: [],
    parentId: ["89134f56-3ef6-ed11-8daf-85953743f5cc"],
  },
];

Each element needs to be given a list of id's of its parents and children.

Here is my function code. It seems I figured out what to do with the children, but there are no ideas at all how to add parents.

export const getFlatList = (classes) => {
  return classes.map((cl) => {
    
    const getChildIds = (classes) => {
      return classes.map((cl) => {
        if (cl.children.length > 0) {
          getChildIds(cl.children);
        } else {
          return cl.id;
        }
        return cl.id;
      });
    };

    return {
      id: cl.id,
      name: cl.name,
      isTransfer: cl.isTransfer,
      children: getChildIds(cl.children),
      parentId: ?? // :(
    };
  });
};

3 Answers 3

1

I came up with something like that. We start from the top and then look for children. If found, we go one level deeper until the children array is empty.

const flattenArray = (array) => {
    let flatArray = [];

    const traverse = (node, parentId = null) => {
        const { children, ...restOfNode } = node;

        flatArray.push({
            ...restOfNode,
            childrenId: children ? children.map(child => child.id) : [],
            parentId: [parentId],
        });

        if (node.children.length) {
            node.children.forEach((child) => traverse(child, node.id));
        }
    }

    array.forEach((arrayItem) => traverse(arrayItem));

    return flatArray;
}

jsfidle: https://jsfiddle.net/wlecki/34cL8jh1/

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

Comments

1

You could create a function getFlatList() to flatten the input, using a recursive approach, iterating through the input and pushing each object found to the result array.

We'd append the parentId and childrenId to each newly created object in the output

function getFlatList ( input, parentId = null) {
    let result = [];
    for(let k in input) {
        if (input[k] && typeof(input[k]) === 'object') {
          if (input[k].name) {
              const { children, ...obj } = input[k]
              result.push({
                  ...obj,
                  childrenId: children.map(c => c.id),
                  parentId
              })
          }
          result.push(...getFlatList(input[k], input.id))
        }
    }
    return result;
}

const transferClasses = [ { id: "c5d91430-aaab-ed11-8daf-85953743f5cc", name: "Class1", isTransfer: false, children: [], }, { id: "775cb75d-aaab-ed11-8daf-85953743f5cc", name: "Class2", isTransfer: false, children: [ { id: "89134f56-3ef6-ed11-8daf-85953743f5cc", name: "Class2-1", isTransfer: false, children: [], }, { id: "89134f56-3ef6-ed11-8daf-85953743f4cc", name: "Class2-2", isTransfer: false, children: [ { id: "89134f56-3ef6-ed11-8daf-85953743f4de", name: "Class2-2-1", isTransfer: false, children: [], }, { id: "89134f56-3ef6-ed11-8daf-85953743f1ce", name: "Class2-2-2", isTransfer: false, children: [], }, ], }, ], }, ];

console.log('Flattened: ');
console.log(getFlatList (transferClasses))
.as-console-wrapper { max-height: 100% !important; }

Comments

1

Here's how I would go about it:

const flatten = (classes, parentId = null) => 
  classes.flatMap(({children = [], id, ...rest}) => [
    {id, ...rest, parentId, childrenId: children.map(({id}) => id)}, 
    ...flatten(children, id)
  ])

const transferClasses = [{id: "c5d91430-aaab-ed11-8daf-85953743f5cc", name: "Class1", isTransfer: false, children: []}, {id: "775cb75d-aaab-ed11-8daf-85953743f5cc", name: "Class2", isTransfer: false, children: [{id: "89134f56-3ef6-ed11-8daf-85953743f5cc", name: "Class2-1", isTransfer: false, children: []}, {id: "89134f56-3ef6-ed11-8daf-85953743f4cc", name: "Class2-2", isTransfer: false, children: [{id: "89134f56-3ef6-ed11-8daf-85953743f4de", name: "Class2-2-1", isTransfer: false, children: []}, {id: "89134f56-3ef6-ed11-8daf-85953743f1ce", name: "Class2-2-2", isTransfer: false, children: []}]}]}]

console.log(flatten(transferClasses))
.as-console-wrapper {max-height: 100% !important; top: 0}

We flatten our list with flatMap, each step returning an array consisting of our current item (without its children property), and the result of recurring on our list of children. We pass parentId through the recursion, defaulting to null if it's not supplied, and we find childrenId by plucking the id values off our children. And that's it. The beauty of recursion handles everything else for us.

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.