接受" params"列表本身?

时间:2014-08-13 06:25:35

标签: c# list params

我试图为项目编写一个方法,该方法将任意数量的列表作为参数,并返回一个包含所有这些列表共享的术语的新列表。我有功能代码,但我更喜欢使用params关键字,而不是必须创建一个列表列表,其中包含我想要比较的所有列表。

static List<T> Shared<T>(List<T> first, List<T> second)
{
    List<T> result = new List<T>();
    foreach (T item in first)
        if (second.Contains(item) && !result.Contains(item)) result.Add(item);
    return result;
}

static List<T> Shared<T>(List<List<T>> lists)
{
    List<T> result = lists.First();

    foreach (List<T> list in lists.Skip(1))
    {
        result = Shared<T>(result, list);
    }

    return result;
}

我当前的代码是否可以比较两个列表,但是为了比较两个以上的列表,我必须创建一个新的列表,如:

List<int> nums1 = new List<int> { 1, 2, 3, 4, 5, 6 };
List<int> nums2 = new List<int> { 1, 2, 3 };
List<int> nums3 = new List<int> { 6, 5, 3, 2 };

List<int> listOfLists = Shared<int>(new List<List<int>> {nums1, nums2, nums3});

foreach (int item in listOfLists)
    Console.WriteLine(item);

//Writes 2 and 3

等。我真的希望能够使用Shared(list1,list2,list3,list4 ...)代替,即使这段代码已经有些功能了。目前,任何使用params版本的尝试都会抱怨&#34;没有超载的方法&#39;共享&#39;需要N个参数&#34;

另外我知道我的代码可能会更有效率地完成,所以我很高兴看到有关这方面的建议,但主要是我需要了解为什么使用params是不工作的 - 如果它&& #39;甚至可能。

3 个答案:

答案 0 :(得分:5)

你在找这个吗?

static List<T> Shared<T>(params List<T>[] lists)

params参数必须始终具有数组类型,但它可以是列表数组。

答案 1 :(得分:1)

可以很容易地安静地完成:

using System.Linq;
// ..
static List<T> Shared<T>(params List<T>[] lists)
{
    if (lists == null)
    {
        throw new ArgumentNullException("lists");
    }  

    return Shared(lists.ToList());
}

答案 2 :(得分:0)

在提出方法签名的@ Selman22的响应的基础上,您可以使用此LINQ查询来实现所需的结果。

static List<T> Shared<T>(params List<T>[] lists)
{
    return 
        lists.Skip(1).Aggregate(    // Skip first array item, because we use it as a seed anyway
        lists.FirstOrDefault(), // Seed the accumulator with first item in the array
        (accumulator, currentItem) => accumulator.Intersect(currentItem).ToList());  // Intersect each item with the previous results
}

我们跳过第一个用作累加器种子的项目,并对给定params数组中每个项目的累加器进行交叉,因为只有所有列表中包含的项目都保存在累加器结果。

要测试它,您可以使用

Shared(nums1, nums2, nums3).ForEach(r => Console.WriteLine(r));