【问题标题】:Check if array of objects, which also contain nested arrays with objects, are the same, if so, combine them into one object and add the keys together检查对象数组是否相同,其中也包含带有对象的嵌套数组,如果是,则将它们合并为一个对象并将键添加到一起
【发布时间】:2021-06-27 21:44:04
【问题描述】:

我需要检查“食物”数组中的对象是否彼此相等,以及那些 - 组合成一个添加量和 mody.amount 并保持其余部分不变。这只是为了更好地显示订单数据。我尝试使用 lodash 库和 reduce,但我不知道如何构造这个嵌套对象(mody)也添加值的函数,如果 isEqual 返回 false,请保留对象同时连接相同的对象。

我尝试了什么:

obj1.reduce((prev, next) => _.isEqual(prev, next) ? {...prev, amount: prev.amount + next.amount} : next

现在看起来是这样的:

 const food =  [
    {
        "id": 1,
        "name": "chicken",
        "price": 6,
        "amount": 1,
        "mody": [
            {
                "id": 33,
                "name": "cheese",
                "price": 1,
                "amount": 1
            },
            {
                "id": 34,
                "name": "chips",
                "price": 2,
                "amount": 1
            }
        ]
    },
    {
        "id": 1,
        "name": "chicken",
        "price": 6,
        "amount": 1,
        "mody": [
            {
                "id": 33,
                "name": "cheese",
                "price": 1,
                "amount": 1
            },
            {
                "id": 34,
                "name": "chips",
                "price": 2,
                "amount": 1
            }
        ]
    },
    {
        "id": 2,
        "name": "pizza",
        "price": 6,
        "amount": 2,
        "mody": [
            {
                "id": 12,
                "name": "extra cheese",
                "price": 2,
                "amount": 1
            }
        ]
    }
]
  

并且需要类似的东西:

const food = [
    {
        "id": 1,
        "name": "chicken",
        "price": 6,
        "amount": 2,
        "mody": [
            {
                "id": 33,
                "name": "cheese",
                "price": 1,
                "amount": 2
            },
            {
                "id": 34,
                "name": "chips",
                "price": 2,
                "amount": 2
            }
        ]
    },
    {
        "id": 2,
        "name": "pizza",
        "price": 6,
        "amount": 2,
        "mody": [
            {
                "id": 12,
                "name": "extra cheese",
                "price": 2,
                "amount": 1
            }
        ]
    }
]
  

【问题讨论】:

标签: javascript arrays lodash reduce


【解决方案1】:

食物量和mod量相加的算法几乎相同,不同之处在于对于每个具有相同id的食物,我们将求和mody量。为了使算法更简单,我使用字典作为 reduce 函数的累加器,因此每个键都有一个唯一元素。这个元素将是我们最后的食物或食物的数量总和。

么和算法:

const sumMody = (modyAccumulator, currentMody) => {
  //Get the stored mody in the accumulator dictionary or null if it the mody is not stored
  const storedMody = modyAccumulator[currentMody.id] ?? null 
  
  // if mody is null then add mody to the dictionary using its id as key
  if (!storedMody) {
    modyAccumulator[currentMody.id] = currentMody
  } else {
    //Mody is stored then sum amount
    storedMody.amount += currentMody.amount
  }

  return modyAccumulator
}

食物总和算法与sumMody相同,唯一的区别是食物相等时调用sumMody函数:

const sumFood = (foodAccumulator, currentFood) => {
  //Get the stored foodin the accumulator dictionary or null if it the food is not stored
  const storedFood = foodAccumulator[currentFood.id] ?? null

  // if food is null then add food to the dictionary using its id as key
  if (!storedFood) {
    foodAccumulator[currentFood.id] = currentFood
  } else {
    //Food is stored then sum food amount
    storedFood.amount += currentFood.amount

    //Create a list with mody from both foods
    const modyList = [...storedFood.mody, ...currentFood.mody]

    //Use reduce passing the sumMody callback function and initialize the accumulator with a dictionary
    const modySumDictionary = modyList.reduce(sumMody, {})

    /* The function above return a dictionary where the identifier is the mody.id 
      and the value is the mody. We only need the values from that dictionary so 
      we use Object.values to extract all the values. */
    storedFood.mody = Object.values(modySumDictionary)
  }

  return foodAccumulator
}

执行两个总和:

//As explained before the reduce function will return a dictionary so we use Object.values to get only the values
const result = Object.values(food.reduce(sumFood, {}))

console.log(result)

没有 cmets 的算法:

const sumMody = (modyAccumulator, currentMody) => {
  const storedMody = modyAccumulator[currentMody.id] ?? null
  if (!storedMody) {
    modyAccumulator[currentMody.id] = currentMody
  } else {
    storedMody.amount += currentMody.amount
  }

  return modyAccumulator
}

const sumFood = (foodAccumulator, currentFood) => {
  const storedFood = foodAccumulator[currentFood.id] ?? null
  if (!storedFood) {
    foodAccumulator[currentFood.id] = currentFood
  } else {
    storedFood.amount += currentFood.amount

    const modyList = [...storedFood.mody, ...currentFood.mody]

    const modySumDictionary  = modyList.reduce(sumMody, {})
    storedFood.mody = Object.values(modySumDictionary)
  }

  return foodAccumulator
}

const result = Object.values(food.reduce(sumFood, {}))

console.log(result)

参考Object.values

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多