【问题标题】:Sort Array of Key-Value Paired Objects using an Array of Arrays使用数组数组对键值对对象数组进行排序
【发布时间】:2020-04-13 09:49:27
【问题描述】:

我正在尝试使用第二个数组数组的索引对一个键值对对象数组进行排序。

考虑以下代码:

const sheet = [['ES'], ['MES'], ['NQ'], ['MNQ']] // sort in this order
const quotes = [{root: 'MNQ'}, {root: 'MES'}, {root: 'ES'}, {root: 'NQ'}] // sort these objects

const sorted = quotes.sort((a, b) => {
  return sheet.indexOf(a.root) - sheet.indexOf(b.root)
})

console.log(sorted)

当您运行上述代码时,sorted 保留了与原始 quotes 变量相同的顺序,并且看起来好像没有进行任何排序!

我觉得我快到了,我的代码只需要稍作调整即可使其正常工作。

【问题讨论】:

  • @CertainPerformance,你能解释一下编辑的原因,这样我就不会再犯同样的错误了吗?
  • meta.stackexchange.com/q/2950 - 这不是一个大问题,但 Stack Overflow 是一个参考站点,而不是一个讨论论坛,所以“谢谢”等只是噪音(我们应该当我们看到它们时将它们从帖子中删除)
  • 已注意到,从现在开始将不再那么“健谈”

标签: javascript arrays sorting object key-value


【解决方案1】:

如果您的quotes 数组具有唯一的{root} 对象,您可以使用一种稍微不同的方法(对于较大的数组,这应该比使用.sort() 更有效)是从您的quotes 创建一个new Map数组然后.map()你的sheet数组{root}对象像这样:

const sheet = [['ES'], ['MES'], ['NQ'], ['MNQ']];
const quotes = [{root: 'MNQ'}, {root: 'MES'}, {root: 'ES'}, {root: 'NQ'}] // sort these objects

const lut = new Map(quotes.map(({root}) => [root, {root}]));
const sorted = sheet.map(([s]) => lut.get(s));
console.log(sorted)

如果你可以有重复,你可以使用.reduce()而不是new Map,然后.flatMap()

const sheet = [['ES'], ['MES'], ['NQ'], ['MNQ']];
const quotes = [{root: 'MNQ'}, {root: 'MES'}, {root: 'ES'}, {root: 'NQ'}, {root: 'MES'}] // sort these objects

const lut = quotes.reduce((acc, {root}) => {
  acc[root] = [...(acc[root] || []), {root}];
  return acc;
}, {});

const sorted = sheet.flatMap(([s]) => lut[s]);
console.log(sorted)

【讨论】:

    【解决方案2】:

    sheet 是一个数组数组,所以sheet.indexOf 任何东西 除了取自sheet 的数组之外,都将返回-1

    先将sheet转换为字符串数组:

    const sheet = [['ES'], ['MES'], ['NQ'], ['MNQ']]
      .map(([str]) => str);
    const quotes = [{root: 'MNQ'}, {root: 'MES'}, {root: 'ES'}, {root: 'NQ'}] // sort these objects
    
    const sorted = quotes.sort((a, b) => {
      return sheet.indexOf(a.root) - sheet.indexOf(b.root)
    })
    
    console.log(sorted)

    或者用.findIndex代替indexOf

    const sheet = [['ES'], ['MES'], ['NQ'], ['MNQ']];
    const quotes = [{root: 'MNQ'}, {root: 'MES'}, {root: 'ES'}, {root: 'NQ'}] // sort these objects
    
    const sorted = quotes.sort((a, b) => {
      return sheet.findIndex(arr => arr[0] === a.root) - sheet.findIndex(arr => arr[0] === b.root)
    })
    
    console.log(sorted)

    或者,为了更好的计算复杂度 (O(n log n)),将sheet 转换为由字符串索引的对象,其值为索引:

    const sheet = [['ES'], ['MES'], ['NQ'], ['MNQ']];
    const sheetObj = {};
    for (const [i, [str]] of sheet.entries()) {
      sheetObj[str] = i;
    }
    const quotes = [{root: 'MNQ'}, {root: 'MES'}, {root: 'ES'}, {root: 'NQ'}] // sort these objects
    
    const sorted = quotes.sort((a, b) => sheetObj[a.root] - sheetObj[b.root]);
    
    console.log(sorted)

    【讨论】:

    • 宾果游戏!非常感谢@CertainPerformance。 15 分钟计时器结束后,我会立即接受您的答复
    【解决方案3】:

    您不能使用indexOf,因为sheet 是一个数组数组。尝试使用findIndex() 并比较唯一的数组元素:

    const sheet = [['ES'], ['MES'], ['NQ'], ['MNQ']] // sort in this order
    const quotes = [{root: 'MNQ'}, {root: 'MES'}, {root: 'ES'}, {root: 'NQ'}] // sort these objects
    
    let sorted = quotes.sort((a, b) => {
      return sheet.findIndex(([x]) => x === a.root) - sheet.findIndex(([x]) => x === b.root);
    })
    
    console.log(sorted);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 2010-09-29
      • 2016-12-23
      相关资源
      最近更新 更多