如何基于List内容循环List

时间:2014-11-03 14:28:17

标签: c# .net linq list

我有一个交易对象:

public class Transaction
{
    public int transactionId {get;set;}
    public string itemName {get;set;}
    public int quantity {get;set;}
}

交易清单可能如下所示(序列化以方便您阅读):

[{transactionId: 1, itemName: 'foo', quantity: 5},
{transactionId: 1, itemName: 'bar', quantity: 5},
{transactionId: 2, itemName: 'example', quantity: 5}]

交易可以包含多个项目。我想基于每个transactionId遍历上面的列表。我想把一个事务变成这样的事情:

public class Transaction
{
    public int transactionId {get;set;}
    public List<Item> itemList = new List<Item>{};
}

对于每个唯一的transactionid,循环遍历所有相关项并将它们放在itemList变量中。序列化后,您最终会得到:

[{transactionId: 1, {{itemName: 'foo', quantity: 5}, {itemName: 'bar', quantity: 5}},
transactionId: 2, {{itemName: 'example', quantity: 5}}}]

需要做什么:遍历列表中的所有事务,并且对于每个唯一的transactionid,将itemName和quantity变量作为新的Item对象放在itemList对象中。类似的东西:

foreach(unique transactionId in item)
{
    item[transactionId].itemList.itemName = item[transactionId].itemName;
    item[transactionId].itemList.quantity= item[transactionId].quantity;
}

我该怎么做?

4 个答案:

答案 0 :(得分:3)

这是GroupBy LINQ operator版本的完美方案:

List<Transaction> transactions = new List<Transaction>();
var groupedTransactions =
    transactions.GroupBy(t => t.transactionId, (key, values) =>
    new TransactionGroup()
    {
        transactionId = key,
        itemList = values.Select(v =>
            new Item()
            {
                itemName = v.itemName,
                quantity = v.quantity
            }).ToList()
    }).ToList();

将类假设为:

public class Transaction
{
    public int transactionId { get; set; }
    public string itemName { get; set; }
    public int quantity { get; set; }
}

public class TransactionGroup
{
    public int transactionId { get; set; }
    public List<Item> itemList = new List<Item> { };
}

public class Item
{
    public string itemName { get; set; }
    public int quantity { get; set; }
}

我在这里使用one of its overloads

public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    Func<TKey, IEnumerable<TSource>, TResult> resultSelector
)

您可以在其中指定分组的关键字以及您希望对每个组值执行什么操作。

答案 1 :(得分:0)

只需迭代数据并将其塑造成您需要的形式。在此代码中,摘要将包含每个id的一个事务对象及其所有项目。

var summary = new Dictionary<int, Transaction>();
foreach(var item in items)
{
    Transaction t;
    if(!summary.TryGetValue(item.Id, t)) 
    {
        t = new Transaction(item.Id);
        summary[t.Id] = t;
    }

    t.Items.Add(new Item { quantity = item.quantity, itemName = item.itemName});
}

答案 2 :(得分:0)

使用GroupBy

public class Transaction2
{
    public int transactionId { get; set; }    
    public List<Item> itemList = new List<Item> { };    
    public class Item
    {
        public string itemName { get; set; }    
        public int quantity { get; set; }
    }
}

....

var list = new List<Transaction>
{
    new Transaction { transactionId = 1, itemName = "foo", quantity = 5 },
    new Transaction { transactionId = 1, itemName = "bar", quantity = 5 },
    new Transaction { transactionId = 2, itemName = "example", quantity = 5 },
};

var list2 = list
    .GroupBy(z => z.transactionId)
    .Select(z => new Transaction2
        {
            transactionId = z.Key,
            itemList = z
                .Select(z2 => new Transaction2.Item 
                {
                    itemName = z2.itemName, 
                    quantity = z2.quantity 
                })
                .ToList()
        })
    .ToList();

答案 3 :(得分:0)

假设您打算调用旧事务OldTransaction,您将在其中创建一个名为ToItem的方法。我正在调用Transaction类,你真正想要的那个:

public Item ToItem() { return new Item(itemName, itemQuantity); }

然后您将旧事务读入字典:

Dictionary<int, Transaction> dict = new Dictionary<int, Transaction>();
foreach (OldTransaction ot in whateverSource) {
    Transacton t = null;
    if (!dict.TryGet(ot.ID, out t)) {
        t = new Transaction(ot.ID);
        dict.Add(ot.ID, t);
    }
    t.items.Add(ot.ToItem());
}

此时你可以遍历dict中的值,你就拥有了你想要的东西。