首页 > 解决方案 > 如何将元组列表与 3 个项目组合在一起,其中 element.item3 == element2.item2

问题描述

我有以下问题:需要对List<Tuple<object, int, int>>不同元素的 item3 等于 item2 进行分组,如果有任何不匹配的元素,它们应该留在当前位置!更加具体List<Tuple<UserDescription, userId, inviterId>>

我尝试过使用 LINQ 的不同方法 - 分组、选择、位置,但没有成功......

var list = new List<Tuple<object, int, int>> // item2 - UserId, item3 - InviterId
    {
        new Tuple<object, int, int>(new { Name = "Ivan" }, 1, 12),
        new Tuple<object, int, int>(new { Name = "George" }, 2, 3),
        new Tuple<object, int, int>(new { Name = "Phil" }, 3, 12),
        new Tuple<object, int, int>(new { Name = "John" }, 4, 3),
        new Tuple<object, int, int>(new { Name = "Giggs" }, 5, 1),
        new Tuple<object, int, int>(new { Name = "Higgins" }, 6, 1)
    };

预期的结果应该是分组元组。Ivan 应该留在当前,因为没有用户 ID 为 12 的用户。他下面应该是 Giggs 和 Higgins,因为他们的邀请者 ID 是 1(Ivan 的用户 ID)等等。结果:

Ivan (user id = 1)
 Giggs (inviter id = 1)
 Higgins (inviter id = 1)
Phil (user id = 3)
 George (inviter id = 3)
 John (inviter id = 3)

标签: c#algorithmlinqsortinggrouping

解决方案


这是我的尝试。注意:此代码假定您的列表索引 = UserId。

var list = new List<Tuple<object, int, int>> // item2 - UserId, item3 - InviterId
        {
            new Tuple<object, int, int>(new { Name = "Ivan" }, 1, 12),
            new Tuple<object, int, int>(new { Name = "George" }, 2, 3),
            new Tuple<object, int, int>(new { Name = "Phil" }, 3, 12),
            new Tuple<object, int, int>(new { Name = "John" }, 4, 3),
            new Tuple<object, int, int>(new { Name = "Giggs" }, 5, 1),
            new Tuple<object, int, int>(new { Name = "Higgins" }, 6, 1)
        };

        var grouped = list.ToLookup(t => t.Item2);

        var withInviter = grouped.Select(grp => Tuple.Create(list[grp.Key], grp));

        var sorted = withInviter.OrderBy(t => t.Item1.Item2);

编辑:对不起,但是当我再次阅读您的示例时,我发现我误解了您正在寻找的结果。我好像可以把用户分为邀请和不邀请?我会更新我的答案,因为它不正确。

编辑2:这个应该工作:

    struct InviterAndInvited {
        public Tuple<object, int, int> Inviter;
        public IEnumerable<Tuple<object, int, int>> Invited;
    }

    public static void Main(string[] args)
    {
        var list = new List<Tuple<object, int, int>> // item2 - UserId, item3 - InviterId
        {
            new Tuple<object, int, int>(new { Name = "Ivan" }, 1, 12),
            new Tuple<object, int, int>(new { Name = "George" }, 2, 3),
            new Tuple<object, int, int>(new { Name = "Phil" }, 3, 12),
            new Tuple<object, int, int>(new { Name = "John" }, 4, 3),
            new Tuple<object, int, int>(new { Name = "Giggs" }, 5, 1),
            new Tuple<object, int, int>(new { Name = "Higgins" }, 6, 1)
        };

        var byInviter = list.ToLookup(u => u.Item3);

        var inviterInveted = list
            .Where(user => byInviter.Contains(user.Item2))
            .Select(user => new InviterAndInvited() {
                Inviter = user,
                Invited = byInviter[user.Item2] 
            } );

        foreach (var grp in inviterInveted) // Print results
        {
            Console.WriteLine(grp.Inviter.Item1);
            foreach (var user in grp.Invited) {
                Console.WriteLine("\t" + user.Item1);
            }
        }
    }

编辑 4:将 GetOrDefault 更改为 []


推荐阅读