【问题标题】:Sorting a multi-dimensional object with hierarchical groups in Javascript (Node.js)在Javascript(Node.js)中对具有分层组的多维对象进行排序
【发布时间】:2013-02-06 17:46:09
【问题描述】:

我有一个分层对象,我通过遍历父对象对子对象进行排序并对子对象进行排序。这行得通。但现在,我需要选择性地打破层次结构并创建新的虚拟约束。

为了说明这一点,让我们举一个男人的例子,他有 x 个妻子。每个妻子,他都有y个孩子。我可以按妻子分孩子,或按男人分妻子。

Man01   Wife01a     Kid01aA
                    Kid01aB
        Wife01b     Kid01bC
                    Kid01bD
Man02   Wife02c     Kid02cE
                    Kid02cF
        Wife02d     Kid02dG
                    Kid02dH

让我们给他们起个名字吧:

Murphy  Winnie  Kurt
                Kara
        Wendy   Klaus
                Klea
Marley  Wonda   Kasper
                Kyra
        Wilma   Kevin
                Karla

并考虑在它们的父母中按字母顺序对它们进行排序:

Marley  Wilma   Karla
                Kevin
        Wonda   Kasper
                Kyra
Murphy  Wendy   Klaus
                Klea
        Winnie  Kara
                Kurt

但是现在,我们希望能够对属于男人、一般妻子或一般孩子的孩子进行排序?

Marley  Wilma   Karla
        Wonda   Kasper
        Wilma   Kevin
        Wonda   Kyra
Murphy  Winnie  Kara
        Wendy   Klaus
        Wendy   Klea
        Winnie  Kurt

这是一个极其简化的虚构对象。实际上,我不是按字母顺序排序,而是对许多属性进行多列排序。

可以将结果输出到表格中,但处理本身已经占用了大量时间和内存。我不想让这进一步复杂化。

如果这没有问题,我只需将对象展平为数组中的表格,将每个多列排序链接到超级多列排序,然后从最近的共同祖先开始重新组合,该祖先通过循环保持完整.

但我正在尝试以更有效的方式解决这个问题,而不是将对象转换为完整的表数组。

  • 我该如何解决这个问题? 实际上循环遍历它们中的每一个两次?
    • 对于这种我还不知道的排序,也许有一个“众所周知的”解决方案?
    • 也许有一种魔法可以使用所有“虚拟”父级的引用创建类似表的记录,然后将这些引用分组回层次结构而不循环它们?

这是我所指的对象类型的示例: Object,我的意思是,字面意思是{},尽管当它有多个成员时,对象包含数组[] 对象{}

{
    "men"   : [
        {
            "name"  : "Murphy",
            // a lot of properties
            "wifes" : [
                {
                    "name"  : "Winnie",
                    // a lot of properties
                    "kids"  : [
                        {
                            "name"  : "Kurt",
                            // a lot of properties
                        }, {}, {} // etc...
                    ]
                }, {}, {} // etc...
            ]
        }, {}, {} // etc...
    ]
}

请注意,在这种情况下,我的示例是错误的,因为 Man、Wife 和 Kid 都是人类。但实际上有不同的对象具有不同的属性。假设有多个宇宙,我应该选择宇宙、行星、土壤或其他东西。 ;)

【问题讨论】:

  • +1 为好名字。但是,您能否告诉我们更多有关您的数据结构的信息,例如JSON-ish 示例对象?你真的需要用 JS 做这种客户端吗,为什么不使用你最喜欢的 DMSDBS?
  • 这是使用 Node.js 的服务器端 javascript。这就是“DMS”。会有很多排序动作,并不是说我可以在某个程序中执行一次并完成它。 :)
  • 你的数据结构是什么,如何存储的?您是否使用某种数据库(这就是我之前拼写错误的“DBS”的意思)?
  • 数据是从其他来源生成和接收的。条目以随机顺序输入,具体取决于所需时间。只有在收到并生成所有内容后才能进行处理。我在问题的末尾添加了一个示例对象。 :)

标签: javascript node.js sorting reference pass-by-reference


【解决方案1】:

我们希望能够对属于男人的孩子进行分类

然后我会这样安排:

Marley  Karla   Wilma   
        Kasper  Wonda
        Kevin   Wilma
        Kyra    Wonda
Murphy  Kara    Winnie
        Klaus   Wendy
        Klea    Wendy
        Kurt    Winnie

当然,由于每个孩子只有一位母亲,因此没有太大差异,但对于您的实际数据,这可能会有所不同。

然而,您现在已经可以看到,您只需对每个人的每个 kids 数组进行排序。

因此,一般来说,您应该先进行分组,然后再对组进行排序,而不是展平为大表数组、多列排序和重新分组结果 - 有点像 bucket sort .

var men = data["men"];
men.forEach(function (man) {
    var kids = {};
    var wifes = man["wifes"];
    for (var i=0; i<wifes.length; i++) {
        var wkids = wifes[i]["kids"];
        for (j=0; j<wkids.length; j++) {
            var id = wkids[j]["name"];
            if (id in kids) {
                kids[id].mothers.push(wifes[i]);
            else {
                kids[id] = wkids[i];
                kids[id].mothers = [ wifes[i] ];
            }
        }
    }
    // if the id is the sort criteria:
    man["kids"] = Object.keys(kids).sort().map(function(id) {
        return kids[id];
    });
    // else build the array first and then sort it:
    // man["kids"] = Object.values(kids).sort(function(kida, kidb) {
    //    <some kid comparison>
    // });

    // you might integrate this loop in the above, but it's independent:
    man["kids"].forEach(function(kid) {
        kid["mothers"].sort( /* some mother comparison */ );
    })
});
// now every man has a sorted "kids" array with each kid having a sorted "mothers" array

【讨论】:

    猜你喜欢
    • 2023-03-23
    • 2016-01-14
    • 2015-07-11
    • 2017-11-09
    • 1970-01-01
    • 2015-01-29
    • 2011-10-23
    • 2020-03-20
    相关资源
    最近更新 更多