合并两个可枚举数,同时保持任一源定义的顺序

问题描述 投票:0回答:1

我需要合并两个枚举,同时保持源枚举中定义的项目的相对顺序。 例如,如果 enumerable1 包含“foxtrot”、“uniform”和“kilo”,而 enumerable2 包含“uniform”、“charlie”和“kilo”,则生成的枚举应包含“foxtrot”、“uniform”、“charlie”、“公斤”。

解释:从 enumerable1 中我们知道“foxtrot”出现在“uniform”之前,从 enumerable2 中我们知道“uniform”出现在“charlie”之前。因此我们可以假设“foxtrot”出现在“uniform”出现在“charlie”之前。 另外,我们从 enumerable1 中知道“uniform”出现在“kilo”之前,并且从 enumerable2 中知道“charlie”出现在“uniform”之后、“kilo”之前。 结合所有这些,我们可以说出“foxtrot”、“uniform”、“charlie”和“kilo”的最终顺序。

然而,在某些情况下这不起作用,因为无法确定顺序或者两个源枚举相互矛盾。 例如,如果 enumerable3 包含“foxtrot”和“charlie”,而 enumerable4 包含“uniform”和“kilo”,则它们无法合并,因为无法区分任何顺序。或者,如果 enumerable5 包含“foxtrot”和“uniform”,而 enumerable6 包含“uniform”和“foxtrot”,则它们无法合并,并且应返回空枚举。

虽然这在我的脑海中很容易想象,但我很难将其转化为代码。最好是 C#。 在这个非常具体的例子中,每个可枚举的最大项目数是 4,但我认为拥有独立于该项目的代码不会有什么坏处。

有人有什么想法吗?

c# merge enumerable
1个回答
0
投票

你可以尝试以下方法,尽管我还没有彻底测试过。

class Program {
    static void Main(string[] args) {
        IEnumerable<string> l1 = new List<string> { "foxtrot", "uniform", "kilo" };
        IEnumerable<string> l2 = new List<string> { "uniform", "charlie", "kilo", "extra1", "extra2" };
        try {
            IEnumerable<string> result = Merge(l1, l2);
            foreach (string s in result) {
                Console.WriteLine(s);
            }
        }
        catch (InvalidOperationException e) {
            Console.WriteLine(e.Message);
        }
        Console.ReadKey();
    }

    public static IEnumerable<T> Merge<T> (IEnumerable<T> list1, IEnumerable<T> list2) {
        if ((list1.Count() == 0)) {
            return list2;
        }
        if ((list2.Count() == 0)) {
            return list1;
        }
        List<T> newList = new List<T>();       
        bool matchfound = false;
        for(int i = 0; i< list1.Count(); i++) {
            for (int j = 0; j < list2.Count(); j++) {
                if (list1.ElementAt(i).Equals(list2.ElementAt(j))) {
                    matchfound = true;
                    newList.AddRange(Merge(list1.Take(i), list2.Take(j)));
                    newList.Add(list1.ElementAt(i));
                    newList.AddRange(Merge(list1.Skip(i + 1), list2.Skip(j + 1)));
                    break;
                }
            }
            if (matchfound) {
                break;
            }
        }
        if (!matchfound) {
            throw new InvalidOperationException("Could not merge");
        }
        return newList;
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.