.net – 如何使用LINQ执行合并排序?

假设您有两个IEnumerbale对象.我们如何合并它们(在某些情况下,例如合并排序合并……)并创建一个独特的IEnumerable?我尝试使用Zip,但在Zip中,两个列表大小应该相等(也许你没有得到异常,但也许我们丢失了一些数据.)

另外,我通过使用Enumerable.Range(…)来尝试它.选择(…)但我没有得到可接受的结果.

此外,我的问题与使用Union或this one完全不同,事实上正如我所说的那样,在合并排序中合并我喜欢保留列表顺序(实际上只是想填补第一个列表中的一些空白).

使用for循环很容易处理它,但我看不到任何完整的linq方式.

编辑:

Sample input:

lst1 = {5,10,12}
lst2 = {7,9,16,20,25}

result: {5,7,9,10,12,16,20,25}

这可以通过for循环和O(n m)中的两个指针来完成,但我正在寻找O(n m)中的linq解决方案

for循环解决方案:

var lst1 = new List<int> { 5, 10, 12 };
        var lst2 = new List<int> { 7, 9, 16, 20, 25 };

        var result = new List<int>();

        int j = 0;
        for (int i = 0; i < lst1.Count; i++)
        {
            while (j < lst2.Count && lst2[j] < lst1[i])
            {
                result.Add(lst2[j]);
                j++;
            }
            result.Add(lst1[i]);
        }

        while (j < lst2.Count)
        {
            result.Add(lst2[j]);
            j++;
        }
        Console.WriteLine(string.Join(",", result.ToArray()));
LINQ中没有这样的方法.而且我认为不可能将现有的方法结合起来完全按照你想要的方式进行(如果是的话,它会过于复杂).

但是自己实现这样的方法并不难:

static IEnumerable<T> Merge<T>(this IEnumerable<T> first,
                               IEnumerable<T> second,
                               Func<T, T, bool> predicate)
{
    // validation ommited

    using (var firstEnumerator = first.GetEnumerator())
    using (var secondEnumerator = second.GetEnumerator())
    {
        bool firstCond = firstEnumerator.MoveNext();
        bool secondCond = secondEnumerator.MoveNext();

        while (firstCond && secondCond)
        {
            if (predicate(firstEnumerator.Current,  secondEnumerator.Current))
            {
                yield return firstEnumerator.Current;
                firstCond = firstEnumerator.MoveNext();
            }
            else
            {
                yield return secondEnumerator.Current;
                secondCond = secondEnumerator.MoveNext();
            }
        }

        while (firstCond)
        {
            yield return firstEnumerator.Current;
            firstCond = firstEnumerator.MoveNext();
        }

        while (secondCond)
        {
            yield return secondEnumerator.Current;
            secondCond = secondEnumerator.MoveNext();
        }
    }
}

你可以像这样使用它:

lst1.Merge(lst2, (i, j) => i < j)
相关文章
相关标签/搜索