在2个具有不同计数的列表上并行进行搜索

时间:2018-06-30 12:56:18

标签: c# .net linq

我需要使用Parallel.ForEach遍历2个具有不同计数的列表。 使用Zip进行了尝试,但是只占用了相同的计数。 我有什么办法可以做到这一点。

请在下面找到我尝试做的示例

List<System> systemT1 = new List<System>() 
{ 
    new System { SystemName = "Test1", Location = "KO",Type = "1" },
    new System { SystemName = "Test2", Location = "AP",Type = "1" },
    new System { SystemName = "Test3", Location = "MP",Type = "1" }
};

List<System> systemT2 = new List<System>() 
{ 
    new System { SystemName = "Test1", Location = "KO",Type = "2" },
    new System { SystemName = "Test2", Location = "AP",Type = "2" }
};

var combined = systemT1.Zip(systemT2, (SystemTy1, SystemTy2) => new { SystemTy1, SystemTy2 });

Parallel.ForEach(combined, pair => 
{
    var systemType1 = pair.SystemTy1;
    ProcessType(systemType1);

    var systemType2 = pair.SystemTy2;
    ProcessType(systemType2);
});

2 个答案:

答案 0 :(得分:-1)

您需要一个ZipLongest扩展方法。试试这个:

public static class Ex
{
    public static IEnumerable<(T1, T2)> ZipLongest<T1, T2>(this IEnumerable<T1> t1, IEnumerable<T2> t2)
    {
        var e1 = t1.GetEnumerator();
        var e2 = t2.GetEnumerator();
        var m1 = e1.MoveNext();
        var m2 = e2.MoveNext();
        while (m1 || m2)
        {
            var c1 = m1 ? e1.Current : default(T1);
            var c2 = m2 ? e2.Current : default(T2);
            yield return (c1, c2);
            m1 = m1 && e1.MoveNext();
            m2 = m2 && e2.MoveNext();
        }
    }
}

然后您可以执行以下操作:

public class MySystem
{
    public string SystemName { get; set; }
    public string Location { get; set; }
    public string Type { get; set; }
}


void Main()
{
    var t1s = new List<MySystem>()
    {
        new MySystem { SystemName = "Test1", Location = "KO", Type = "1" },
        new MySystem { SystemName = "Test2", Location = "AP", Type = "1" },
        new MySystem { SystemName = "Test3", Location = "MP", Type = "1" },
    };

    var t2s = new List<MySystem>()
    {
        new MySystem { SystemName = "Test1", Location = "KO", Type = "2" },
        new MySystem { SystemName = "Test2", Location = "AP", Type = "2" },
    };

    var combined = t1s.ZipLongest(t2s);

    Parallel.ForEach(combined, pair =>
    {
        var (t1, t2) = pair;
        ProcessType(t1);
        ProcessType(t2);
    });
}

combined的结果是:

combined

答案 1 :(得分:-2)

我可以为您建议一个自定义的Zip方法,该方法将在最长集合的末尾显示。

    static IEnumerable<Tuple<System, System>> ZipLongest(IEnumerable<System> T1, IEnumerable<System> T2)
    {
        //We want to enumerate to the longest collection
        int length = Math.Max(T1.Count(), T2.Count());
        var e1 = T1.GetEnumerator();
        var e2 = T2.GetEnumerator();
        //We will use this to output null if a collection does not contain new elements
        var e1Done = false;
        var e2Done = false;
        for (int i = 0; i < length; i++)
        {
            e1Done = !e1.MoveNext();
            e2Done = !e2.MoveNext();
            var system1 = e1Done ? null : e1.Current;
            var system2 = e2Done ? null : e2.Current;
            yield return new Tuple<System, System>(system1, system2);
        }
    }

我使用了一个元组,但是您可以使用ValueTuple或自定义对象来获得漂亮的项目命名。

这是基于您的问题的我的示例测试应用程序:

    class System
    {
        public string SystemName { get; set; }
        public string Location { get; set; }
        public string Type { get; set; }
    }

    static void Main(string[] args)
    {
        List<System> systemT1 = new List<System>()
        {
            new System { SystemName = "Test1", Location = "KO",Type = "1" },
            new System { SystemName = "Test2", Location = "AP",Type = "1" },
            new System { SystemName = "Test3", Location = "MP",Type = "1" }
        };

        List<System> systemT2 = new List<System>()
        {
            new System { SystemName = "Test1", Location = "KO",Type = "2" },
            new System { SystemName = "Test2", Location = "AP",Type = "2" }
        };

        //var combined = systemT1.Zip(systemT2, (SystemTy1, SystemTy2) => new { SystemTy1, SystemTy2 });
        var combined = ZipLongest(systemT1, systemT2);

        Parallel.ForEach(combined, pair =>
        {
            //var systemType1 = pair.SystemTy1;
            var systemType1 = pair.Item1;
            //ProcessType(systemType1);

            //var systemType2 = pair.SystemTy2;
            var systemType2 = pair.Item2;
            //ProcessType(systemType2);
        });
    }

希望这可以解决您的问题。