使用数组数组对键值对对象数组进行排序

Sort Array of Key-Value Paired Objects using an Array of Arrays

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

考虑以下代码:

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 变量相同的顺序,并且看起来好像没有发生任何排序!

我觉得我已经差不多了,我的代码只需要稍作调整就可以正常工作。

sheet 是数组的数组,所以 sheet.indexOf 除了取自 sheet 的数组之外的任何东西 都将 return -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)

您不能使用 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);

如果您的 quotes 数组具有唯一的 {root} 对象,您可以使用一种略有不同的方法(对于更大的数组应该比使用 .sort() 更有效) new Map from your quotes array and then .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() instead of a new Map, and then .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)