2

I have an array of objects which is nested. How do I make an array of objects with this one getting values from nested properties as well? If onClick property is empty, it means there is a property called children and the parent element should not be a part of the new list. I need to loop through the children array and get the values. Please see the expected output below.

const headers = [{
    title: 'Arun',
    id: 'arunId',
    onClick: 'onClickArun'
  },
  {
    title: "George",
    id: 'georgeId',
    onClick: '',
    children: [{
        title: 'David',
        id: 'davidId',
        onClick: 'onClickDavid'
      },
      {
        title: 'Patrick',
        id: 'patrickId',
        onClick: 'onClickPatrick'
      }
    ]
  },
  {
    title: 'Mark',
    id: 'markId',
    onClick: 'onClickMark'
  }
];

console.log(headers.map(item => {
  return {
    title: item.title,
    onClick: item.onClick
  }
}))

Expected Output:

[{
    title: 'Arun',
    onClick: 'onClickArun'
  },
  {
    title: 'David',
    onClick: 'onClickDavid'
  },
  {
    title: 'Patrick',
    onClick: 'onClickPatrick'
  },
  {
    title: 'Mark',
    onClick: 'onClickMark'
  }
]

Any help is greatly appreciated.

4 Answers 4

4

You could take Array#flatMap with a recursive callback.

const
    map = ({ title, onClick, children }) => onClick
        ? { title, onClick }
        : children.map(map);

var headers = [{ title: 'Arun', id: 'arunId', onClick: 'onClickArun' }, { title: "George", id: 'georgeId', onClick: '', children: [{ title: 'David', id: 'davidId', onClick: 'onClickDavid' }, { title: 'Patrick', id: 'patrickId', onClick: 'onClickPatrick' }] }, { title: 'Mark', id: 'markId', onClick: 'onClickMark' }],        
    result = headers.flatMap(map);

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

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

Comments

2

You can do this using Array.prototype.reduce, where you just need to check if the parent onClick prop is empty and the children prop is present or not:

var headers = [{ title: 'Arun', id: 'arunId', onClick: 'onClickArun' }, { title: "George", id: 'georgeId', onClick: '', children: [{ title: 'David', id: 'davidId', onClick: 'onClickDavid' }, { title: 'Patrick', id: 'patrickId', onClick: 'onClickPatrick' }] }, { title: 'Mark', id: 'markId', onClick: 'onClickMark' }];


function getObject(headers, acc){
  return headers.reduce((acc, ele) => {
   if(!ele.onClick.length && ele.children){
      acc = getObject(ele.children, acc);
   }else{
      acc.push({"title": ele.title, "onClick": ele.onClick});
   }
   return acc;
  }, acc);
}
console.log(getObject(headers, []));

2 Comments

Good answer, but your solution does not take into account nested children.
@YuriKhomyakov yeah sorry, If forgot to add the recursive step which is needed here.
1

Looks like you need a depth first search. You run on the array, for each item with children recurse on it and pass along the existing array. otherwise, add the item to the list.

function getChildren(array, total = []){
  for(let item of array) {
    if(item.children) {
      getChildren(item.children, total)
    } else {
      total.push({
        title: item.title,
        onClick: item.onClick
      })
    }
  }
  return total
}

Comments

1
let headers = [{
  title: 'Arun',
  id: 'arunId',
  onClick: 'onClickArun'
},
{
  title: "George",
  id: 'georgeId',
  onClick: '',
  children: [{
    title: 'David',
    id: 'davidId',
    onClick: 'onClickDavid'
  },
  {
    title: 'Patrick',
    id: 'patrickId',
    onClick: 'onClickPatrick'
  }
  ]
},
{
  title: 'Mark',
  id: 'markId',
  onClick: 'onClickMark'
}
]
// take children, only if onClick is empty
.map(item => item.onClick ? item : item.children)
// make flat array
headers = [].concat.apply([], headers)
    .map(item => { 
        const temp = {};
        temp.title = item.title;
        temp.onClick = item.onClick;
        return temp; // take only onClick and title property from each item
})


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.