[英]How do I sort an array of objects based on another array of objects
我有一個動態調整大小的數組,該數組根據最后選擇的位置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
解決。 在以下示例中,排序將根據prevRates
數組將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);
如果先map
,則可以使用indexOf
完成相同的操作。 這會導致代碼更簡潔:
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
創建的原始索引的哈希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
。 當您想退回原始訂單時,使用該紙張進行排序,避免多余的副本。 假設這就是您想要做的!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.