【问题标题】:how do you loop through a List based on List contents如何根据列表内容循环遍历列表
【发布时间】:2014-11-03 14:28:16
【问题描述】:

我有一个交易对象:

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和数量变量放在itemList对象中作为一个新的Item对象。比如:

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

我该怎么做?

【问题讨论】:

  • 不应该itemNamequantityItem 的一部分吗?
  • 错字!我编辑了代码。
  • 所以真正的问题是您有一些格式错误的数据需要输入正确的格式?
  • 听起来你需要GroupBy
  • 你定义到Transaction类,先相互分离

标签: c# .net linq list


【解决方案1】:

这是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
)

您可以在其中指定分组的键是什么,以及您想对每个分组值做什么。

【讨论】:

  • 如果初始项目是这样的,这不起作用。 [{transactionId:1,itemName:'foo',数量:5},{transactionId:1,itemName:'foo',数量:2}]
  • @HPT,不确定这是否是 OP 的问题......你假设他想要组项目,这并不那么明显。
【解决方案2】:

只需迭代数据并将其塑造成您需要的形式。在此代码中,摘要将包含每个 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});
}

【讨论】:

  • 如果初始项目是这样的,这不起作用。 [{transactionId:1,itemName:'foo',数量:5},{transactionId:1,itemName:'foo',数量:2}]
【解决方案3】:

使用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();

【讨论】:

  • 如果初始项目是这样的,这不起作用。 [{transactionId:1,itemName:'foo',数量:5},{transactionId:1,itemName:'foo',数量:2}]
  • 它应该导致 [{transactionId: 1, {{itemName: 'foo', quantity: 7}}] 但它会导致 [{transactionId: 1, {{itemName: 'foo' , 数量: 5}, {itemName: 'foo', 数量: 2}}]
  • @HPT 您假设 OP 想要按 itemName 和添加数量进行分组,问题中的什么让您这么认为?
【解决方案4】:

假设您要调用旧事务 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 中的值,得到你想要的。

【讨论】:

  • 如果初始项目是这样的,这不起作用。 [{transactionId:1,itemName:'foo',数量:5},{transactionId:1,itemName:'foo',数量:2}]
  • 问题陈述中没有说明。
猜你喜欢
  • 1970-01-01
  • 2012-04-01
  • 1970-01-01
  • 2013-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-31
相关资源
最近更新 更多