Create Javascript Object Having Nested Parent Objects

ⅰ亾dé卋堺 提交于 2021-02-05 07:57:27

问题


I am working on a Nodejs project. I have to create a function which takes an object (a child category) like:

{
    id: 65,
    name: 'Outdoor',
    parent_id: 2
}

Now I want my function to check for the parent category by using parent_id from database and return an array/object like this:

{
    id: 2,
    name: 'Furniture',
    parent: {
        id: 1,
        name: 'Residential',
        parent: {
            id: ...,
            name: ...,
            parent: {
                and so on..
            }
        }
    }
}

This is what I have done so far:

* _get_category_parents(category, _array) {

    if(_array === undefined) _array = []

    if( category.parent_id !== 0 ) {
      const c_parent = yield this.Database.from('categories').where('id', '=', category.parent_id)
      _array.push({id: c_parent[0].id, name: c_parent[0].name})
      yield this._get_category_parents(c_parent[0], _array)

    }

    return _array

  }

And calling this function like this:

const parents = yield this._get_category_parents(category)

This returns me an array of parents like this:

[
    {
        "id": 2,
        "name": "Furniture"
    },
    {
        "id": 1,
        "name": "Residential"
    }
]

I want Residential object to be appended in Furniture's parent node.

I have spent too much time on this but not getting what I want. Any help would be deeply appreciated.


回答1:


What you want to think about is a recursive solution.

Since you're calling a database, it's probably unlikely, but if the lookup by id is synchronous, you might do it with code something like the following (note that I'm faking a db here):

const getHierarchy = (lookup, child) => {
  const {id, name, parent_id} = lookup(child) || 
        {id: null, name: null, parent_id: 0}
  return parent_id == 0  
         ? {id, name, parent_id} 
         :  {...{id, name},  ...{parent: getHierarchy(lookup, {parent_id})}}
}

const items = [
  {id: 1, name: 'Residential', parent_id: 5},
  {id: 2, name: 'Furniture', parent_id: 1},  
  {id: 3, name: 'Other', parent_id: 0},   
  {id: 4, name: 'FooBar', parent_id: 3},   
  {id: 5, name: 'Stuff', parent_id: 0} 
]

const lookup = child => items.find(item => item.id == child.parent_id)

const item = {id: 65, name: 'Outdoor', parent_id: 2}

console.log(getHierarchy(lookup, item))

You would have to write an appropriate lookup function, presumably using this.Database.from(...). You might also want to simplified version that bakes in your lookup function, in which case, you might write

const getAncestry = (item) => getHierarchy(lookup, item)

If, as seems more likely, your lookup is asynchronous, then that will affect getHierarchy and how you call it. Here's one possibility:

const getHierarchy = async (lookup, child) => {
  const {id, name, parent_id} = await lookup(child) || 
        {id: null, name: null, parent_id: 0}
  return parent_id == 0  
         ? {id, name, parent_id} 
         :  {...{id, name},  ...{parent: await getHierarchy(lookup, {parent_id})}}
}

const items = [
  {id: 1, name: 'Residential', parent_id: 5},
  {id: 2, name: 'Furniture', parent_id: 1},  
  {id: 3, name: 'Other', parent_id: 0},   
  {id: 4, name: 'FooBar', parent_id: 3},   
  {id: 5, name: 'Stuff', parent_id: 0} 
]

const lookup = async child => new Promise(
  (resolve, reject) => setTimeout(
    () => resolve(items.find(item => item.id == child.parent_id)), 
    1000
  )
)
const getAncestry = async item => getHierarchy(lookup, item)

const item = {id: 65, name: 'Outdoor', parent_id: 2}

getAncestry(item).then(console.log)

Note the change in how you call the function. You need to call .then() on the resulting promise to get any useful behavior.



来源:https://stackoverflow.com/questions/48769989/create-javascript-object-having-nested-parent-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!