如何按类别获取最小值的对象

问题描述 投票:0回答:1

我相信我有一个如下的javascript对象数组,我试图过滤掉每件商品的所有价格,但最低价格除外。

有:

const fruits = [
    {id: 1, fruit: "apple", store: "store1", price: 1},
    {id: 2, fruit: "apple", store: "store2", price: 1.25},
    {id: 3, fruit: "banana", store: "store1", price: 0.5},
    {id: 4, fruit: "banana", store: "store2", price: 0.75},
    {id: 5, fruit: "banana", store: "store3", price: 0.75}
];

Want:

[
    {id: 1, fruit: "apple", store: "store1", price: 1},
    {id: 3, fruit: "banana", store: "store1", price: 0.5}
];

我想在SQL中,这可以通过一个group by语句来实现,比如 "select fruit, min(price) from table group by fruit",但我不知道如何以当前对象的形式来实现。

我正在寻找一个JavaScript解决方案,但如果需要的话,我愿意改变数据结构或使用一个框架。如果相关的话,我已经在使用React.js了。有任何指导吗?

javascript
1个回答
1
投票

对象赋值和减少。

const fruits = 
      [ { id: 1, fruit: "apple",  store: "store1", price: 1    } 
      , { id: 2, fruit: "apple",  store: "store2", price: 1.25 } 
      , { id: 3, fruit: "banana", store: "store1", price: 0.5  } 
      , { id: 4, fruit: "banana", store: "store2", price: 0.75 }  
      , { id: 5, fruit: "banana", store: "store3", price: 0.75 } 
      ] 


const mini = fruits.reduce((a,c)=>
              {
              let x = a.find(e=>e.fruit===c.fruit)
              if (!x) a.push(Object.assign({},c))
              else if (x.price > c.price) Object.assign(x,c)
              return a  
              },[])


console.log(  mini  )

- Dave Newton : . 通过基于mapobject的解决方案,你可以对水果进行一次迭代,让结果对象处理查找。

还有一种方法。

const fruits = 
      [ { id: 1, fruit: "apple",  store: "store1", price: 1    } 
      , { id: 2, fruit: "apple",  store: "store2", price: 1.25 } 
      , { id: 3, fruit: "banana", store: "store1", price: 0.5  } 
      , { id: 4, fruit: "banana", store: "store2", price: 0.75 }  
      , { id: 5, fruit: "banana", store: "store3", price: 0.75 } 
      ] 


const mini = fruits.reduce((a,c,i,t)=>
              {
              if (!a.find(e=>e.fruit===c.fruit))
                a.push(t.filter(e=>e.fruit===c.fruit).reduce((r,n)=>r.price<n.price?r:n) ) 
              return a  
              },[])

console.log( mini )

1
投票

你可以通过一个 减少 操作,创建一个 地图种类 (fruit)到最低价格记录。

例如

const fruits = [
  {id: 1, fruit: "apple", store: "store1", price: 1},
  {id: 2, fruit: "apple", store: "store2", price: 1.25},
  {id: 3, fruit: "banana", store: "store1", price: 0.5},
  {id: 4, fruit: "banana", store: "store2", price: 0.75},
  {id: 5, fruit: "banana", store: "store3", price: 0.75}
]

const result = [...fruits.reduce((map, entry) => {
  // check for an existing record and if it has a greater price
  if (!map.has(entry.fruit) || map.get(entry.fruit).price > entry.price) {
    // set the new record for this category
    map.set(entry.fruit, entry)
  }
  return map
}, new Map()).values()] // now just get the values

console.info(result)

如果有多个相同价格的条目,将保留第一个找到的条目。如果您想保留最后一个,请使用 >= 而不是比较。


0
投票

groupBy 是一个很好的常用操作,可以方便使用。 我首先会用它来按果实对对象进行分组。 第二个reduce(minInArray)也是一个常用的形式,用来寻找一个数组中的最小值或最大值。 它们一起产生每个水果类型的最小值......。

const groupBy = (array, key) => {
  return array.reduce(function(r, a) {
    r[a[key]] = r[a[key]] || []
    r[a[key]].push(a)
    return r
  }, {})
}

const minInArray = (array, key) => {
  return array.reduce((prev, curr) => {
    return prev[key] < curr[key] ? prev : curr
  })
}

const fruits = [{
  id: 1,
  fruit: "apple",
  store: "store1",
  price: 1
}, {
  id: 2,
  fruit: "apple",
  store: "store2",
  price: 1.25
}, {
  id: 3,
  fruit: "banana",
  store: "store1",
  price: 0.5
}, {
  id: 4,
  fruit: "banana",
  store: "store2",
  price: 0.75
}, {
  id: 5,
  fruit: "banana",
  store: "store3",
  price: 0.75
}];




let groups = groupBy(fruits, 'fruit')
let minPrices = Object.keys(groups).map(fruit => {
  return minInArray(groups[fruit], 'price')
})

console.log(minPrices)
© www.soinside.com 2019 - 2024. All rights reserved.