javascript - 如何根据另一个对象数组对对象数组进行排序
问题描述
我有一个动态大小的数组,它根据最后选择到数组位置 0 的内容更改其顺序。问题是我想保持数组的原始顺序。
为此,我创建了一个附加变量,该变量设置为数组的原始排序。尽管数组的某些值在选择项目后可能会发生变化,但 name 属性永远不会发生变化。我想利用这个事实将新数组排序到原始位置。
let keepRateOrder = rates.sort((a, b) => {
return prevRates.indexOf(a.name) - prevRates.indexOf(b.name);
});
const rates = [
{name:'UPS', isChoosen:true, cost:63 ...},
{name:'Mail', isChoosen:false, cost:23 ...},
{name:'FedEx', isChoosen:false, cost:33 ...}
]
const prevRates = [
{name:'Mail', isChoosen:false, cost:23 ...},
{name:'UPS', isChoosen:true, cost:63 ...},
{name:'FedEx', isChoosen:false, cost:33 ...}
]
解决方案
这可以使用findIndex
. 在以下示例中,排序将Mail
根据prevRates
数组放在第一位:
const rates = [
{name:'UPS', isChoosen:true, cost:63},
{name:'Mail', isChoosen:false, cost:23},
{name:'FedEx', isChoosen:false, cost:33}
];
const prevRates = [
{name: 'Mail'},
{name: 'UPS'},
{name: 'FedEx'},
];
let keepRateOrder = rates.sort((a, b) => {
return prevRates.findIndex(p => p.name === a.name) - prevRates.findIndex(p => p.name === b.name);
});
console.log(keepRateOrder);
indexOf
如果你是第一个,你可以完成同样的事情map
。这导致代码更简洁:
const rates = [
{name:'UPS', isChoosen:true, cost:63},
{name:'Mail', isChoosen:false, cost:23},
{name:'FedEx', isChoosen:false, cost:33}
];
const prevRates = [
{name: 'Mail'},
{name: 'UPS'},
{name: 'FedEx'},
].map(x => x.name);
let keepRateOrder = rates.sort((a, b) => {
return prevRates.indexOf(a.name) - prevRates.indexOf(b.name);
});
console.log(keepRateOrder);
这是另一种解决方案,仅使用原始索引的哈希,使用以下方法创建reduceRight
:
const rates = [
{name:'UPS', isChoosen:true, cost:63},
{name:'Mail', isChoosen:false, cost:23},
{name:'FedEx', isChoosen:false, cost:33}
]
const prevRates = [
{name: 'Mail'},
{name: 'UPS'},
{name: 'FedEx'},
].reduceRight((a, x, i) => (a[x.name] = i, a), {});
let keepRateOrder = rates.sort((a, b) => {
return prevRates[a.name] - prevRates[b.name];
});
console.log(keepRateOrder);
由于您说可以从原始数组中添加或删除项目,请注意上述所有解决方案都将首先放置新项目(因为它们在prevRates
数组中的索引将返回为-1
)。如果您希望新项目出现在最后,您需要执行以下操作:
const rates = [
{name:'UPS', isChoosen:true, cost:63},
{name:'Mail', isChoosen:false, cost:23},
{name:'Foo'},
{name:'FedEx', isChoosen:false, cost:33},
];
const prevRates = [
{name: 'Mail'},
{name: 'UPS'},
{name: 'FedEx'},
].map(x => x.name);
let keepRateOrder = rates.sort((a, b) => {
const aIndex = prevRates.indexOf(a.name);
const bIndex = prevRates.indexOf(b.name);
return (aIndex === -1 ? Number.MAX_VALUE : aIndex) - (bIndex === -1 ? Number.MAX_VALUE : bIndex);
});
console.log(keepRateOrder);
推荐阅读
- python - 如何在python中将列表转换为csv文件
- flutter - Flutter将带有数组子对象和对象的json转换为类映射
- c# - NotifyCollectionChangedEventArgs:添加的项目未出现在给定索引处(在删除期间)
- xcode - 如何在可执行文件附近生成 dsym 文件,而不是在捆绑包之外,最好没有安装后脚本?
- android - 在 Android Studio 中找不到 Sync with Gradle 按钮
- c# - 如何将C#中两个标签的数量相乘
- scala - scala/spark - 对数据框进行分组并从其他列中选择值作为数据框
- python - 如何将最后一列(1d 数组)附加到 python 中的 2d numpy 数组?
- google-apps-script - 使用外部脚本在新创建的 Google 电子表格中写入
- flutter - 下拉菜单中有多个订单项时底部溢出