JS:按特定顺序获取对象的ID

时间:2018-12-07 17:58:08

标签: javascript arrays object ecmascript-6

我需要以正确的层次结构顺序获取一组对象的所有ID。

更新:在此示例中,ID按字母顺序排列,但它们应表示随机字符串。

[
  { _id: 'abc', parent: 'mainID', main: 'mainID', order: 1, type: 'item' },
  { _id: 'def', parent: 'mainID', main: 'mainID', order: 2, type: 'item' },
  { _id: 'ghi', parent: 'mainID', main: 'mainID', order: 3, type: 'group' },
  { _id: 'jkl', parent: 'ghi', main: 'mainID', order: 1, type: 'item' },
  { _id: 'mno', parent: 'ghi', main: 'mainID', order: 2, type: 'group' },
  { _id: 'pqr', parent: 'mno', main: 'mainID', order: 1, type: 'item' },
  { _id: 'stu', parent: 'mainID', main: 'mainID', order: 4, type: 'item' }
]

让我简要说明一下我的数据结构: 有几项(type)。在第一级中,所有项目/组均具有父级mainID

因此,对于第一级元素,其ID为:['abc','def','ghi','stu']。 第三个元素(ghi是一个 group 元素,它具有另外两个子元素-子元素具有父ghi

第二个子元素('mno')也是一个组,具有一个子元素。

初始数组中的对象可以按随机顺序排列,这对我来说是个问题。 每个级别中元素的顺序由顺序值(升序)确定。

所以初始数组也可能像这样:

[
  { _id: 'ghi', parent: 'mainID', main: 'mainID', order: 3, type: 'group' },
  { _id: 'jkl', parent: 'ghi', main: 'mainID', order: 1, type: 'item' },
  { _id: 'mno', parent: 'ghi', main: 'mainID', order: 2, type: 'group' },
  { _id: 'pqr', parent: 'mno', main: 'mainID', order: 1, type: 'item' },
  { _id: 'stu', parent: 'mainID', main: 'mainID', order: 4, type: 'item' },
  { _id: 'abc', parent: 'mainID', main: 'mainID', order: 1, type: 'item' },
  { _id: 'def', parent: 'mainID', main: 'mainID', order: 2, type: 'item' }
]

以更好的视觉方式,对象表示此结构:

abc
def
ghi
  jkl
  mno
    pqr
stu

我需要的是ID从上到下的顺序

所以结果应该是:

['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu']

由于嵌套结构,我的尝试无效:

(elements) => {
  const result = []
  elements
    .filter(item => (item.parent === item.main))
    .forEach(elm => {
      result.push(elm._id)
      if (elm.type === 'group') {
        getOrderedId(elements, elm._id)
      }
    })
  return result
}

1 个答案:

答案 0 :(得分:1)

我首先要创建一个由_id值键控的Map,其中每个条目都以一个空数组开头,该数组需要填充该父级的子级(如果有子级)。添加了一个额外的键来表示main条目,即根。

然后只需迭代输入,即可将每个对象注入上述树结构的适当数组中。

然后最终在该树结构中进行有序遍历(使用递归),并在对象被访问时产生它们。

以下代码假定:

  • 所有对象都属于同一棵树(具有相同的main属性)。
  • order的值不会以1开头的空缺。

未使用type属性-它是冗余信息。

function ordered(elements) {
    if (!elements.length) return [];
    const rootId = elements[0].main;
    const children = new Map(elements.map(e => [e._id, []])).set(rootId, []);
    elements.forEach(e => children.get(e.parent)[e.order-1] = e);
    return [...(function * visit(id) {
        if (!children.has(id)) return;
        for (let child of children.get(id)) {
            yield child;
            yield * visit(child._id);
        }
    })(rootId)];
}

const elements = [{ _id: 'ghi', parent: 'mainID', main: 'mainID', order: 3, type: 'group' }, { _id: 'jkl', parent: 'ghi', main: 'mainID', order: 1, type: 'item' }, { _id: 'mno', parent: 'ghi', main: 'mainID', order: 2, type: 'group' }, { _id: 'pqr', parent: 'mno', main: 'mainID', order: 1, type: 'item' }, { _id: 'stu', parent: 'mainID', main: 'mainID', order: 4, type: 'item' }, { _id: 'abc', parent: 'mainID', main: 'mainID', order: 1, type: 'item' }, { _id: 'def', parent: 'mainID', main: 'mainID', order: 2, type: 'item' }];

console.log(ordered(elements));