在对象数组中匹配对象键并返回具有最高值的键、值对

4
我有一个对象数组,每个对象都有一个"baseAsset key"和"Volume"属性,但是每个对象的"Volume"值都不同。我想匹配"baseAsset key"并返回具有最高"Volume"值的对象。由于该数组包含3000多个对象,效率和速度很重要。
let tickerA = [{
    pair: 'AUDUSD',
    baseAsset: 'AUD',
    lastPriceUSD: 0.74,
    volume: 1000
}, {
    pair: 'AUDUSD',
    baseAsset: 'AUD',
    lastPriceUSD: 0.76,
    volume: 2000
}, {
    pair: 'USDEUR',
    baseAsset: 'USD',
    lastPriceUSD: 1.25,
    volume: 1200
}, {
    pair: 'USDEUR',
    baseAsset: 'USD',
    lastPriceUSD: 1.19,
    volume: 1500
}]

函数的预期返回值

tickerB = [{
    baseAsset: 'AUD',
    lastPriceUSD: 0.76,
    volume: 2000
}, {
    baseAsset: 'USD',
    lastPriceUSD: 1.25,
    volume: 1500
}]

不清楚你为什么希望 USD 交易量为 1500,而该项的 lastPriceUSD 是 1.19,而非你提到的 1.25。这只是笔误吗? - Mark
4个回答

1
你可以通过循环遍历并将最大项保存到对象中,在O(n)时间内完成此操作。最终,你的值将在组的Object.values中:

let tickerA = [{pair: 'AUDUSD',baseAsset: 'AUD',lastPriceUSD: 0.74,volume: 1000}, {pair: 'AUDUSD',baseAsset: 'AUD',lastPriceUSD: 0.76,volume: 2000}, {pair: 'USDEUR',baseAsset: 'USD',lastPriceUSD: 1.25,volume: 1200}, {pair: 'USDEUR',baseAsset: 'USD',lastPriceUSD: 1.19,volume: 1500}]

let groups = tickerA.reduce((largest, {baseAsset, lastPriceUSD, volume}) => {
    /* 
     * if it's a new baseAsset or bigger than a previous one, save it
     * to the group under the baseAsset key 
    */
    if (!largest[baseAsset] || largest[baseAsset]['volume'] < volume ) {
        largest[baseAsset] = {baseAsset, lastPriceUSD, volume}
    }

    return largest
}, {})

TickerB = Object.values(groups)
console.log(TickerB)


1
一种方法是迭代 tickerA 的值,并将其映射到 baseAsset 键,如果该项的 volume 值大于该 baseAsset 键的当前项的值。

let tickerA = [{
    pair: 'AUDUSD',
    baseAsset: 'AUD',
    lastPriceUSD: 0.74,
    volume: 1000
}, {
    pair: 'AUDUSD',
    baseAsset: 'AUD',
    lastPriceUSD: 0.76,
    volume: 2000
}, {
    pair: 'USDEUR',
    baseAsset: 'USD',
    lastPriceUSD: 1.25,
    volume: 1200
}, {
    pair: 'USDEUR',
    baseAsset: 'USD',
    lastPriceUSD: 1.19,
    volume: 1500
}];

/* Use map to relate baseAsset key of tickerA item with current max volume value */
const map = new Map()

/* Iterate tickerA items, searching for greatest volume value per baseAsset class */
for(const item of tickerA) {
  
  const assetMatch = map.get(item.baseAsset);
  
  if(assetMatch && item.volume < assetMatch.volume) {
    /* If matching item (by asset found) with volume greater than that of current tickerA
    item, then disregard the current item */
    continue;
  }
  else {
    /* Otherwise, this tickerA item is; the first of the asset class, or greater in volume
    so we'll update the map entry for this asset class */
    map.set(item.baseAsset, item);
  }  
}
 
/* Extract the map values as an array */
const tickerB = Array.from(map.values());

console.log(tickerB);


0

这个替代方案将baseAsset分组,并在最后提取分组的值。

这是一个O(n)时间复杂度。

let tickerA = [{pair: 'AUDUSD',baseAsset: 'AUD',lastPriceUSD: 0.74,volume: 1000}, {pair: 'AUDUSD',baseAsset: 'AUD',lastPriceUSD: 0.76,volume: 2000}, {pair: 'USDEUR',baseAsset: 'USD',lastPriceUSD: 1.25,volume: 1200}, {pair: 'USDEUR',baseAsset: 'USD',lastPriceUSD: 1.19,volume: 1500}];
let result = Object.values(tickerA.reduce((a, {baseAsset, lastPriceUSD, volume}) => {
    let {volume: current} = a[baseAsset] || {volume: Number.MAX_SAFE_INTEGER};
    
    if (current < volume) a[baseAsset].volume = volume;
    else a[baseAsset] = {baseAsset, lastPriceUSD, volume};
    
    return a;
}, Object.create(null)));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


0

使用 reduceObject.values

let tickerA = [{pair: 'AUDUSD',baseAsset: 'AUD',lastPriceUSD: 0.74,volume: 1000}, {pair: 'AUDUSD',baseAsset: 'AUD',lastPriceUSD: 0.76,volume: 2000}, {pair: 'USDEUR',baseAsset: 'USD',lastPriceUSD: 1.25,volume: 1200}, {pair: 'USDEUR',baseAsset: 'USD',lastPriceUSD: 1.19,volume: 1500}];
const res = Object.values(tickerA.reduce((acc, { baseAsset, lastPriceUSD, volume }) => {
  acc[baseAsset] = (!acc[baseAsset] || acc[baseAsset].volume < volume) ? { baseAsset, lastPriceUSD, volume } : acc[baseAsset];
  return acc;
}, {}));
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接