我有一个基于对什么是最后的选择到阵列的0位置,改变其顺序的动态调整大小的数组。问题是,我想保持阵列的原始顺序。
为了做到这一点,我已经创建了被设置为阵列的原始排序的附加变量。虽然有些数组的值可能会在项目的选择后更改的名称属性从来不会。我想利用这一点来的新阵原来的位置排序。
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);
首先使用.map
改造prevRates
逼到name
属性数组,然后你可以使用基于.sort
名字是阵列上:
const prevRates = [
{name:'Mail', isChoosen:false, cost:23 },
{name:'UPS', isChoosen:true, cost:63 },
{name:'FedEx', isChoosen:false, cost:33 }
];
const rates = [
{name:'UPS', isChoosen:true, cost:63 },
{name:'Mail', isChoosen:false, cost:23 },
{name:'FedEx', isChoosen:false, cost:33 }
];
const prevRatesNames = prevRates.map(({ name }) => name);
rates.sort((a, b) => (
prevRatesNames.indexOf(a.name) - prevRatesNames.indexOf(b.name)
));
console.log(rates);
请记住,.sort
各种就地 - 如果你这样做
let keepRateOrder = rates.sort...
然后keepRateOrder
将只是另一个参考rates
阵列。如果你想要一个副本,而不是突变原rates
阵列,那么你就必须要浅拷贝rates
第一:
const keepRateOrder = rates.slice().sort...
如何添加新的属性,以每个项目跟踪原来的指数,originalIndex
。排序使用,当你想在原来的顺序背,避免了额外的副本。假设这就是你想要做什么!