Lodash 或 JavaScript 等效于 LINQ Group by & Select FirstOrDefault()



i有具有AuthorizationOrder的商店的 list ,我需要在JavaScript中拉出分组集合的firstOrDefault值。

eg: storeDto : { StoreNumber = 1 , Warehouse = 4201, AuthorizationOrder = 1 },
               { StoreNumber = 2 , Warehouse = 4201, AuthorizationOrder = 2 },
               { StoreNumber = 1 , Warehouse = 4202, AuthorizationOrder = 2 },
               { StoreNumber = 1 , Warehouse = 4203, AuthorizationOrder = 3 },
               { StoreNumber = 2 , Warehouse = 4207, AuthorizationOrder = 1 }

使用linq:

warehouseStoreList = warehouseStoreList.GroupBy(x => x.StoreNumber)
      .Select(g => g.OrderBy(x => x.AuthorizationOrder).FirstOrDefault()).ToList();

Result: { StoreNumber = 1 , Warehouse = 4201, AuthorizationOrder = 1 },
        { StoreNumber = 2 , Warehouse = 4207, AuthorizationOrder = 1 }

我如何使用Lodash或JavaScript进行类似的操作,通过在商店上进行分组,在AuthorizationOrder上订购后获取第一值。

另外,请使用相关商店的仓库。请参阅使用Linq

实现的小提琴

小提琴:https://dotnetfiddle.net/glc1ij

想要使用JavaScript或lodash实现同样的事情。

您可以根据StoreNumber使用reduce进行组。创建一个具有唯一唯一唯一StoreNumber的蓄能器,作为这样的键:

{
  "1": {
    "StoreNumber": 1,
    "Warehouse": 4201,
    "AuthorizationOrder": 1
  },
  "2": {
    "StoreNumber": 2,
    "Warehouse": 4207,
    "AuthorizationOrder": 1
  }
}

如果key不存在或当前AuthorizationOrder小于累加器的值,则更新该值。然后使用Object.values()将值仅获取到一个数组:

const array = [{StoreNumber:1,Warehouse:4201,AuthorizationOrder:1},{StoreNumber:2,Warehouse:4201,AuthorizationOrder:2},{StoreNumber:1,Warehouse:4202,AuthorizationOrder:2},{StoreNumber:1,Warehouse:4203,AuthorizationOrder:3},{StoreNumber:2,Warehouse:4207,AuthorizationOrder:1}]
const grouped = array.reduce((acc, o) => {
  let group = acc[o.StoreNumber];
  
  if(!group || group.AuthorizationOrder > o.AuthorizationOrder)
    acc[o.StoreNumber] = o;
  return acc;
}, {})
console.log(Object.values(grouped))

您可以通过以下步骤执行此操作:

  • reduce()应用于对象数组,然后将累加器设置为空对象{}
  • 对象的键将是storeNumber,值将为对象。
  • 检查特定密钥处的对象的AuthorizationOrder是否大于我们要迭代的元素的AuthorizationOrder,然后将该键的值更改为当前元素。否则不要更改它。
  • 最终使用Object.values()获取一系列对象。

const arr = [{ StoreNumber:1 , Warehouse:4201, AuthorizationOrder:1 },
               { StoreNumber:2 , Warehouse:4201, AuthorizationOrder:2 },
               { StoreNumber:1 , Warehouse:4202, AuthorizationOrder:2 },
               { StoreNumber:1 , Warehouse:4203, AuthorizationOrder:3 },
               { StoreNumber:2 , Warehouse:4207, AuthorizationOrder:1 }]
               
const res = arr.reduce((ac,a) => {
  let ao = a.AuthorizationOrder
  let ao2 = (ac[a.StoreNumber] || {}).AuthorizationOrder || Infinity 
  if(ao < ao2) ac[a.StoreNumber] = a;
  return ac
},{});
console.log(Object.values(res))

使用lodash/fp,您可以通过StoreNumber对项目进行分组,然后将每个组映射到最小AuthorizationOrder值的项目:

const { flow, groupBy, map, minBy } = _
const fn = flow(
  groupBy('StoreNumber'),
  map(minBy('AuthorizationOrder'))
)
const array = [{StoreNumber:1,Warehouse:4201,AuthorizationOrder:1},{StoreNumber:2,Warehouse:4201,AuthorizationOrder:2},{StoreNumber:1,Warehouse:4202,AuthorizationOrder:2},{StoreNumber:1,Warehouse:4203,AuthorizationOrder:3},{StoreNumber:2,Warehouse:4207,AuthorizationOrder:1}]
const result = fn(array)
console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

最新更新