【问题标题】:Sorting array of objects matching ids on a different set对与不同集合上的 id 匹配的对象数组进行排序
【发布时间】:2018-03-28 07:13:17
【问题描述】:

我有一个对象数组

array = [
    {id: 5, name: "Helen", age: 20}, 
    {id: 15, name: "Lucy", age: 30}, 
    {id:7, name: "Carlos", age: 1}
]

然后我有一个类似的数组以不同的方式排序

arraySorted = [        
    {id: 15, name: "Lucy", age: 2}, 
    {id: 5, name: "Lara", age: 11}, 
    {id:7, name: "Carlos", age: 10}
]

两个数组上的对象的 id 总是匹配的,其余的属性可能会也可能不会。

我需要按照与arraySorted 相同的id 顺序对数组进行排序。

(也可以在普通的JavaScript 上完成,lodash 不是必需的,但也许会有用)

【问题讨论】:

    标签: javascript arrays sorting lodash


    【解决方案1】:

    请参阅MapArray.prototype.map() 了解更多信息。

    // Raw.
    const raw = [
        {id: 5, name: "Helen", age: 20}, 
        {id: 15, name: "Lucy", age: 30}, 
        {id:7, name: "Carlos", age: 1}
    ]
    
    // Sorted.
    const sorted = [        
        {id: 15, name: "Lucy", age: 2}, 
        {id: 5, name: "Lara", age: 11}, 
        {id:7, name: "Carlos", age: 10}
    ]
    
    // Match.
    const match = (raw, sorted) => (m => sorted.map(s => m.get(s.id)))(new Map(raw.map(r => [r.id, r])))
    
    // Output.
    const output = match(raw, sorted)
    
    // Proof.
    console.log(output)

    【讨论】:

    • 与使用find (+1) 的解决方案相比,这是一个更好的解决方案。
    • @trincot 为什么它更优秀
    • Array.prototype.find() 每次调用时都会执行一次盲搜索。 Map.get() 使用集合 keys 检索 values。这些属性严重影响time complexity
    • 其他解决方案使用带有forEachmap 的主循环,就像这里一样,但是它们通过调用find 在其中有一个隐式的嵌套 循环,它将启动从左到右搜索数组,这意味着 findO(n) 时间复杂度运行。因此,整体时间复杂度变为O(n²)。另一方面,这里有三个非嵌套循环(一个循环运行另一个循环完成后):两个Array#map 调用和一个带有new Map 调用的隐式迭代。 m.get 以恒定时间运行,因此整体时间复杂度为 O(n+n+n) = O(n)
    【解决方案2】:

    不要使用sort,而是使用mapfindObject.assign

    arraySorted.map( s => Object.assign( s, array.find( t => t.id == s.id ) ) );
    

    演示

    var array = [{
        id: 5,
        name: "Helen",
        age: 20
      },
      {
        id: 15,
        name: "Lucy",
        age: 30
      },
      {
        id: 7,
        name: "Carlos",
        age: 1
      }
    ];
    var arraySorted = [{
        id: 15,
        name: "Lucy",
        age: 2
      },
      {
        id: 5,
        name: "Lara",
        age: 11
      },
      {
        id: 7,
        name: "Carlos",
        age: 10
      }
    ];
    array = arraySorted.map(s => Object.assign(s, array.find(t => t.id == s.id)));
    
    console.log(array);

    【讨论】:

      【解决方案3】:

      新数组可以通过Array.prototype.map获取:

      const newArray = arraySorted.map(sortedItem => 
        array.find(item => item.id === sortedItem.id)
      )
      
      console.log(newArray)
      

      【讨论】:

        【解决方案4】:

        您可以使用 Map,并且 避免 使用嵌套迭代方法(例如 find,这会使解决方案的时间复杂度更差),假设您确实具有所有相同的 id 值两个数组:

        const array = [{id: 5, name: "Helen", age: 20}, {id: 15, name: "Lucy", age: 30}, {id:7, name: "Carlos", age: 1}],
            arraySorted = [{id: 15, name: "Lucy", age: 2},{id: 5, name: "Lara", age: 11},{id:7, name: "Carlos", age: 10}]
        
        const result = arraySorted.map((map => row => array[map.get(row.id)])
                                       (new Map(array.map((row, i) => [row.id, i]))));
        
        console.log(result);

        【讨论】:

        • 是的,我一直都有相同的 ID。
        【解决方案5】:

        试试这个,希望对你有帮助

        var array=[{id:5,name:"Helen",age:20},{id:15,name:"Lucy",age:30},{id:7,name:"Carlos",age:1}];
        
        var arraySorted=[{id:15,name:"Lucy",age:2},{id:5,name:"Lara",age:11},{id:7,name:"Carlos",age:10}];
        
        array = arraySorted.map(s => array.find(t => t.id == s.id));
        
        console.log(array);

        【讨论】:

          【解决方案6】:

          您可以使用Map 对数组进行排序:

          let a1 = [{id: 5, name: "Helen", age: 20}, {id: 15, name: "Lucy", age: 30}, {id:7, name: "Carlos", age: 1}],
              a2 = [{id: 15, name: "Lucy", age: 2}, {id: 5, name: "Lara", age: 11}, {id:7, name: "Carlos", age: 10}];
          
          let map = ((m) => (
                       a2.forEach(({id}) => m.set(id, a1.find(o => o.id === id))), m
                    ))(new Map());
          
          let result = [...map.values()];
          
          console.log(result);
          .as-console-wrapper { max-height: 100% !important; top: 0; }

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-07-21
            • 1970-01-01
            • 2021-10-21
            • 2015-05-11
            • 1970-01-01
            • 2019-08-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多