按照另一个深度嵌套的对象数组对深度嵌套的对象数组进行排序的最佳性能方法

3
作为示例,我包含了一个只有一个元素的数组,它包含一个具有Children键的对象,该键是一个对象数组,每个对象也具有其自己的Children键,其中包含另一个数组。
[
  {
    "Id": "1",
    "Children": [
      {
        "Id": "2",
        "Children": [
          {
            "Id": "10",
            "DisplayName": "3-4",
          },
          {
            "Id": "1000",
            "DisplayName": "5-6",
          },
          {
            "Id": "100",
            "DisplayName": "1-2",
          },
        ]
      }
    ]
  }
]

我需要比较第二个对象数组和第一个对象数组,并确保第一个数组的顺序与第二个对象数组相同。如果不同,则进行排序,使其相同。

以下是第二个对象数组:

[
  {
    "Id": "1",
    "Children": [
      {
        "Id": "2",
        "Children": [
           {
            "Id": "100",
            "DisplayName": "1-2",
          },
          {
            "Id": "10",
            "DisplayName": "3-4",
          },
          {
            "Id": "1000",
            "DisplayName": "5-6",
          },
        ]
      }
    ]
  }
]

这将运行在数万条数据上,因此性能至关重要。
我目前尝试的方法是使用实用程序方法将第二个数组的每个元素转换为键控对象的对象,例如:
{
   1:  {
        "Id": "1",
        "Children": [
          {
            "Id": "2",
            "Children": [
              {
                "Id": "4",
                "DisplayName": "3-4",
              },
              {
                "Id": "3",
                "DisplayName": "1-2",
              },
            ]
          }
        ]
      }
}

这样可以快速从顶层进行查找。我在想是否应该一直这样做,还是有一种惯用的方法可以实现这一点。我也考虑过递归。

已排序数组的顺序不是基于Id的 - 它是任意的。因此,需要保留顺序。


这些对象是否保证具有相同的深度,并且它们在每个级别上包含相同数量的子元素? - charlietfl
只要一个键存在于其中一个对象中,另一个对象中相应的键就会具有相同的深度。但是,在参考对象中存在的键可能在被比较的数组中不存在。我将尝试使用您提供的示例,并且可能需要使用pluck/filter来获取两者相同,然后运行递归函数。 - zero_cool
1个回答

0
假设每个对象的每个级别都存在相同的深度和所有ID,使用递归函数匹配,在排序回调中使用{{link1:Array#findIndex()}}。

function sortChildren(main, other) {
  other.forEach((o, i) => {
    if (o.children) {
      const mChilds = main[i].children, oChilds = o.children;
      
      oChilds.sort((a, b) => {
        return mChilds.findIndex(main => main.Id === a.Id) - mChilds.findIndex(main => main.Id === b.Id)
      });
      // call function again on this level passing appropriate children arrays in
      sortChildren(mChilds, oChilds)
    }
  })
}

sortChildren(data, newData);
console.log(JSON.stringify(newData, null, ' '))
<script>
  var data = [{
    "Id": "1",
    "Children": [{
      "Id": "2",
      "Children": [{
          "Id": "3",
          "DisplayName": "1-2",
        },
        {
          "Id": "4",
          "DisplayName": "3-4",
        },
      ]
    }]
  }]

  var newData = [{
    "Id": "1",
    "Children": [{
      "Id": "2",
      "Children": [{
          "Id": "4",
          "DisplayName": "3-4",
        },
        {
          "Id": "3",
          "DisplayName": "1-2",
        },
      ]
    }]
  }]

</script>


我需要排序的数据存在一个问题,即id参数不是按升序/降序排列的。您如何保持顺序不变呢? - zero_cool
正在使用相关ID的索引。 - charlietfl
@zero_cool Id 的顺序?认为对象键具有可预测的顺序是有风险的:https://dev59.com/Ul0a5IYBdhLWcg3wqaNS(如果您指的是数组索引位置,请忽略我的评论。 :) ) - stealththeninja
不,每个对象都是children数组的元素。它在其children数组中的索引。这是数组索引...与对象属性顺序无关。 - charlietfl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接