合并两个列表并根据等级排列合并列表 [英] Merge two lists and arrange merged list based on rank

查看:138
本文介绍了合并两个列表并根据等级排列合并列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个列表,我正在尝试将它们合并,合并后,我的列表应按等级升序排列.

I have two lists and I am trying to merge them and after merging, my list should be in ascending order by rank.

代码:

 public class Test
    {
        public int TestId { get; set; }
        public List<VariantsRank> VariantsRanks { get; set; }
    }

    public class VariantsRank
    {
        public int VariantId { get; set; }
        public string Name { get; set; }
        public int Rank { get; set; }
    }
    public class Class1
    {
        public void Process()
        {
            var List1 = new Test();
            List1.TestId = 100;
            List1.VariantsRanks.Add(new VariantsRank { VariantId = 10, Name = "V1", Rank = 0 });
            List1.VariantsRanks.Add(new VariantsRank { VariantId = 11, Name = "V2", Rank = 1 });
            List1.VariantsRanks.Add(new VariantsRank { VariantId = 12, Name = "V3", Rank = 2 });
            List1.VariantsRanks.Add(new VariantsRank { VariantId = 13, Name = "V4", Rank = 3 });
            List1.VariantsRanks.Add(new VariantsRank { VariantId = 14, Name = "V5", Rank = 4 });

            List1.VariantsRanks.Add(new VariantsRank { VariantId = 15, Name = "V6", Rank = 5 });
            List1.VariantsRanks.Add(new VariantsRank { VariantId = 16, Name = "V7", Rank = 6 });
            List1.VariantsRanks.Add(new VariantsRank { VariantId = 17, Name = "V8", Rank = 7 });

            var List2 = new Test();
            List2.TestId = 100;
            List2.VariantsRanks.Add(new VariantsRank { VariantId = 17, Name = "V8", Rank = 0 });
            List2.VariantsRanks.Add(new VariantsRank { VariantId = 15, Name = "V6", Rank = 1 });
            List2.VariantsRanks.Add(new VariantsRank { VariantId = 16, Name = "V7", Rank = 2 });
            List2.VariantsRanks.Concat(List1.VariantsRanks).GroupBy(x => x.VariantId).SelectMany(x => x.Take(1)).ToList();
        }
    }

我得到的输出:

VariantId = 10, Name = "V1", Rank = 0
VariantId = 11, Name = "V2", Rank = 1
VariantId = 12, Name = "V3", Rank = 2
VariantId = 13, Name = "V4", Rank = 3
VariantId = 14, Name = "V5", Rank = 4

VariantId = 15, Name = "V6", Rank = 5
VariantId = 16, Name = "V7", Rank = 6
VariantId = 17, Name = "V8", Rank = 7

预期输出:

List1.TestId = 100
[0] : VariantId = 10, Name = "V1", Rank = 0
[1] : VariantId = 11, Name = "V2", Rank = 1
[2] : VariantId = 12, Name = "V3", Rank = 2
[3] : VariantId = 13, Name = "V4", Rank = 3
[4] : VariantId = 14, Name = "V5", Rank = 4
[5] : VariantId = 17, Name = "V8", Rank = 5
[6] : VariantId = 15, Name = "V6", Rank = 6
[7] : VariantId = 16, Name = "V7", Rank = 7

现在,我想合并2个列表,对于列表1中匹配的那些记录,那么我想优先考虑列表2的记录,因此列表2的v8,v6和v7应该替换列表1的记录,即v6,v7和v8.

Now I would like to merge 2 list and for those records which are matching in list1 then I would like to give priority to list 2 records so v8,v6 and v7 of list 2 should replace list 1 records i.e v6,v7 and v8.

推荐答案

按照我的理解,可以通过这种方式定义问题.给定两个有序列表,请根据第二个列表中的顺序对第一个列表中的匹配项重新排序,并将第二个列表中不匹配的项添加到第一个列表的末尾.

The way I understand it, the problem can be defined this way. Given a two ordered lists, reorder the matching items in the first list according to their order in the second list, add unmatched items from the second list at the end of the first list.

我将从第二个列表中准备有序匹配项的队列开始:

I would start by preparing a queue of the ordered matches from the second list:

var matchQueue = new Queue<VariantsRank>(
    from r2 in List2.VariantsRanks
    join r1 in List1.VariantsRanks on r2.VariantId equals r1.VariantId
    orderby r2.Rank
    select r2);

然后是具有匹配键的HashSet:

var matchSet = new HashSet<int>(matchQueue.Select(r2 => r2.VariantId));

我们将按顺序处理第一个列表,然后对每个元素使用matchSet来确定是否存在匹配项,如果是,则将使用下一个匹配项准备好的matchQueue.

We are going to process the first list in order, then for each element will use the matchSet to determine if there is match, and if yes, will take the next match in order using the prepared matchQueue.

然后,我们将按顺序附加第二个列表中不匹配的元素.最后,我们将迭代生成的序列(应该按照前面的步骤正确排序)并更新排名.

Then we'll append the unmatched elements from the second list in order. Finally we'll iterate the resulting sequence (which should be ordered correctly from the previous steps) and update the ranks.

所有翻译成LINQ的内容如下:

All that translated to LINQ looks like this:

var result = List1.VariantsRanks
    .OrderBy(r1 => r1.Rank)
    .Select(r1 => matchSet.Contains(r1.VariantId) ? matchQueue.Dequeue() : r1)
    .Concat(List2.VariantsRanks
    .Where(r2 => !matchSet.Contains(r2.VariantId))
    .OrderBy(r2 => r2.Rank))
    .Select((r, i) => new VariantsRank { VariantId = r.VariantId, Name = r.Name, Rank = i })
    .ToList();

这篇关于合并两个列表并根据等级排列合并列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆