从TypeScript中的每个组中检索n个项目

时间:2019-04-26 21:17:56

标签: javascript angular typescript

我想从打字稿中的列表中从每个组中取出N个项目。在使用linq的c#中,我会做类似的事情,但是我不确定如何在打字稿中做到这一点。

var rr = db.Products.GroupBy(x => x.ProductSubTypeCategoryId).Select(g => new { GroupName = g.Key, Items = g.Take(4).ToList() });

我的模特是

const lstTrade : Trade [] = [
  { contractName: 'Contract1' ,amount : 12}, 
  { contractName: 'Contract1' ,amount : 12},
  { contractName: 'Contract1' ,amount : 20},
  { contractName: 'Contract2' ,amount : 20},
  { contractName: 'Contract2' ,amount : 20},
  { contractName: 'Contract2' ,amount : 20}
];

我有一个贸易项目清单。现在我要实现的是从上面的清单中仅获得2个具有不同合同名称的项目。在这种情况下,两个合同1和两个合同2。

2 个答案:

答案 0 :(得分:0)

在用任何语言谈论数组和集合时,总是可以通过reduce解决所有可能的基于数组的问题,这是将数组简化为一个对象,并按每个contractName对其进行分组,从这里您可以随意处理很多每个人都想要。

const lstTrade = [
  { contractName: 'Contract1' ,amount : 12}, 
  { contractName: 'Contract1' ,amount : 12},
  { contractName: 'Contract1' ,amount : 20},
  { contractName: 'Contract2' ,amount : 20},
  { contractName: 'Contract2' ,amount : 20},
  { contractName: 'Contract2' ,amount : 20}
];


const intoObject = lstTrade.reduce<Record<string, typeof lstTrade>>((grouped, curr) => {
  return {...grouped, [curr.contractName]: (grouped[curr.contractName] || []).concat(curr)}
}, {})

/*
{
    Contract1: [{contractName: 'Contract1, amount: 12'}, {contractName: ....}...]
    Contract2: [...]
}
*/

答案 1 :(得分:0)

来自Shanon的答案是正确的,但仅按部分代码提供给您。我将提供两个示例,一个用于GroupBy,一个用于Take,这两个示例一起使用可以为您解决问题。

也请注意,我展示的GroupBy和Take例子不是我的。值得一提的是此页面http://complexitymaze.com/2014/04/03/cheat-sheet-from-basic-linq-to-javascript/,我想您会发现它对javascript中的许多其他LINQ类型任务很有帮助(请注意,使用javascript是在打字稿中处理数组的方式)

GroupBy

C#

var result = persons.GroupBy(person => person.lastname);

打字稿

let result = persons.reduce((previous, person) => {
    (previous[person.lastname] = previous[person.lastname] || []).push(person);
    return previous;
}, []);

参加

C#

var result = persons.Take(2);

打字稿

let result = persons.slice(0, 2);

所以对于您的情况,我会写以下内容

const lstTrade : Trade [] = [
  { contractName: 'Contract1' ,amount : 12}, 
  { contractName: 'Contract1' ,amount : 12},
  { contractName: 'Contract1' ,amount : 20},
  { contractName: 'Contract2' ,amount : 20},
  { contractName: 'Contract2' ,amount : 20},
  { contractName: 'Contract2' ,amount : 20}
];

let result = lstTrade.reduce((previous, trade) => {
    (previous[trade.contractName] = previous[trade.contractName] || []).push(trade);
    return previous;
}, [])
// now it is an object with groupedTrades as properties but we want to only get a certain number of items in each group
for (const groupName in result) {
    result[groupName] = result[groupName].slice(0, 2);
}