LINQ GroupBy返回List作为结果

时间:2015-01-29 10:24:49

标签: c# linq

我有一个包含Transaction对象的List。我要做的是找到所述List中具有相同transaction.Buyer.UserID的事务,并将它们组合成一个列表列表。

每个子列表项都将包含多个事务对象,其中transaction.Buyer.UserID是相同的。

到目前为止我所拥有的是:

            var _ordersToCombine = 
            _transactions.GroupBy(transaction => transaction.Buyer.UserID).Select(transaction => transaction);

我进来了:

List<Transaction>:
    Transaction { Buyer.UserID = "User1" ...}
    Transaction { Buyer.UserID = "User2" ...}
    Transaction { Buyer.UserID = "User1" ...}
    Transaction { Buyer.UserID = "User3" ...}
    Transaction { Buyer.UserID = "User4" ...}
    Transaction { Buyer.UserID = "User3" ...}

我期望它返回的是:

List<List<Transaction>>:
    List<Transaction>:
        Transaction { Buyer.UserID = "User1" ...}
        Transaction { Buyer.UserID = "User1" ...}
    List<Transaction>:
        Transaction { Buyer.UserID = "User3" ...}
        Transaction { Buyer.UserID = "User3" ...}

...并且还从主列表中删除这些事务,因此在此示例中,主列表将如下所示:

List<Transaction>:
    Transaction { Buyer.UserID = "User2" ...}
    Transaction { Buyer.UserID = "User4" ...}

Linq对我来说是一个全新的概念,我正试图解决这个问题。

5 个答案:

答案 0 :(得分:5)

只需使用它进行分组:

var results = transactions
.GroupBy(p => p.Buyer.UserID)
.Where(x=>x.Count()>1)
.Select(x=> new List<Transaction>(x));

这应该会从主列表中生成重复用户的List<List<Transaction>。 在迭代它时,LINQ不是修改集合的正确工具。如果你真的需要它,请执行:

var results = transactions.ToList()
.GroupBy(p => p.Buyer.UserID)
.Where(x=>x.Count()>1)
.Select(x=> 
{
    foreach(var item in x)
        transactions.Remove(item);
    return new List<Transaction>(x);
});

请注意,事务列表的副本用于执行(transactions.ToList()上的查询,并在原始列表上执行删除操作。希望这有帮助。

答案 1 :(得分:1)

试试这个:

var dic = _transactions.GroupBy(t => t.Buyer.UserID).ToDictionary(t => t.Key, t => t.ToList());

GroupBy返回

IEnumerable<IGrouping<TKey, TSource>>

每个IGrouping&lt;&gt;包含密钥,组标准,每个IGrouping都是可枚举的(列出分组值)

因为,问题发生了变化:

不要在GroupBy委托中创建匿名类型(没有新的{...}) 相反,直接定位属性(因为在内部,GroupBy使用相等来对事物进行分组,因为您创建了一个新的匿名对象,所以没有任何分组,因为每个新对象都是不同的对象)

.GroupBy(o => o.Buyer.UserID, o.ToList) 

此外,

Select(p => p) 

什么都不做,这是一个身份功能。这没用。

如果你想要的是List列表,我想你可以直接使用Dictionary。 (请参阅我的答案的第一部分)您可以按照枚举List的相同方式枚举字典。并在其中添加/删除/替换项目。

返回的词典将是以下类型:

Dictionary<int,List<Transactions>> dic =....

使用Key = UserId,以及每个键,一个事务列表。 而且,它实际上比列表列表更快,因为您可以直接访问事务:

int userId = 42;
List<Transactions> transactions = dic[userId];

答案 2 :(得分:1)

如果我理解正确,

你有一个交易清单, 和列表的交易清单。

你需要对后者进行分组, 通过userId,其中值将是与该用户对应的事务。

如果是这样的话, 我准备了一个可能有帮助的小样本。

祝你好运

public class Transaction
{
    public Buyer Buyer { get; set; }
}

public class Buyer
{
    public int UserID { get; set; }
}


[TestMethod]
public void Test()
{

    var t1 = new Transaction { Buyer = new Buyer { UserID = 1 } };
    var t2 = new Transaction { Buyer = new Buyer { UserID = 2 } };
    var t3 = new Transaction { Buyer = new Buyer { UserID = 3 } };
    var t4 = new Transaction { Buyer = new Buyer { UserID = 1 } };
    var t5 = new Transaction { Buyer = new Buyer { UserID = 3 } };

    var tList1 = new List<Transaction> { t1, t2, t3 };
    var tList2 = new List<Transaction> { t4, t5 };

    var tLists = new List<List<Transaction>> { tList1 , tList2};

    var result = tLists.
        SelectMany(o => o).
        GroupBy(o =>  new 
        {
            UserId = o.Buyer.UserID
        },
        (key, items) => new
        {
            UserId = key.UserId,
            Transactions = items.Select(p => p).ToList()
        }).
        ToList();
}

这是作者编辑的更新解决方案:

    var transactions = new List<Transaction>
    {
        new Transaction { Buyer = new Buyer { UserID = 1 } },
        new Transaction { Buyer = new Buyer { UserID = 2 } },
        new Transaction { Buyer = new Buyer { UserID = 3 } },
        new Transaction { Buyer = new Buyer { UserID = 1 } },
        new Transaction { Buyer = new Buyer { UserID = 3 } }
    };

    var result = transactions.
        Select(o => o).
        GroupBy(o => new
        {
            UserId = o.Buyer.UserID
        },
        (key, items) => new
        {
            //UserId = key.UserId,
            Transactions = items.Select(p => p).ToList()
        }).
        ToList();

答案 3 :(得分:0)

您是否收到IEnumerable<IGrouping<TKey, TSource>>请参阅:MSDN Group By

所以基本上它返回一个组列表。该组包含分组的键和元素,该元素是属于该组的项目列表

列表

  • 第1组
    • 组密钥
    • 项目(对象列表)
  • 第2组
    • 组密钥
    • 项目(对象列表)

很好的解释:https://www.udemy.com/blog/linq-group-by/

答案 4 :(得分:0)

Group by in LINQ

这可以回答您的问题。

var results = transactions.GroupBy(p => p.Buyer.UserID,
                         (key, g) => new { UserID = key, Cars = g.ToList() });