簡體   English   中英

如何基於另一個對象數組對一個對象數組進行排序

[英]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); 

首先使用.mapprevRates轉換為僅包含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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM