【问题标题】:Accept "params" which are lists themselves?接受列表本身的“参数”?
【发布时间】:2014-08-13 06:25:35
【问题描述】:

我正在尝试为一个项目编写一个方法,该方法将任意数量的列表作为参数,并返回一个包含所有这些列表共享的术语的新列表。我有功能代码,但我更喜欢使用 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 版本的尝试都会抱怨“方法 'Shared' 没有重载需要 N 个参数”

此外,我知道我的代码可能会更有效地完成,所以我也很高兴看到有关这方面的建议,但首先我需要弄清楚为什么使用 params 不起作用 - 如果它甚至可能的话。

【问题讨论】:

标签: c# list params


【解决方案1】:

你在找这个吗?

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

params 参数必须始终具有 array 类型,但它可以是 List 的数组。

【讨论】:

  • 好吧,我现在觉得自己非常愚蠢。非常感谢:)
  • 显然,它仍然计划C# 6 到达时改变这一点(参见Params IEnumerable
【解决方案2】:

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

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

    return Shared(lists.ToList());
}

【讨论】:

    【解决方案3】:

    基于提出方法签名的@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
    }
    

    我们跳过用作累加器种子的第一个项目,并为给定参数数组中的每个项目与累加器相交,因为只有包含在所有列表中的项目才会保留在累加器结果。

    要测试它,你可以使用

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

    【讨论】:

      猜你喜欢
      • 2021-06-07
      • 2012-07-22
      • 1970-01-01
      • 2021-10-29
      • 2016-06-25
      • 1970-01-01
      • 2018-05-27
      • 2020-06-14
      • 1970-01-01
      相关资源
      最近更新 更多