【问题标题】:C # Compare 2 lists of ints of different sizeC#比较2个不同大小的int列表
【发布时间】:2018-11-25 09:04:56
【问题描述】:

我目前有 2 个列表要比较,它们的长度永远不会相等。

List<int> data,长度为 n

List<int> numbersToSeekFor,长度为 n,包含 data 中所有不同值的集合

List<Color> colorsToAssign的长度与numbersToSeekFor相同

我想要实现但不是很成功的是将data 中的所有项目与numbersToSeekFor 的每个索引进行比较。如果此条件为真,colorsToAssign 中的第一个 index 将被添加到列表中,然后是第二个索引,依此类推...

下面的一个非常愚蠢的例子就是这个方法。如果我假设numbersToSeekFor 中有 3 个元素。此方法的输出列表也应与data 大小相同。

public List<Color> Foo(List<int> data, List<int>numbersToSeekFor, List<Color> colorsToAssign)
  {
    List<Color> colors = new List<Color>();
    for (int i = 0; i < data.Count; i++)
    {



        if(data[i] == numbersToSeekFor[0])
        {
          colors.Add(colorsToAssign[0]);

        }

        if(data[i] == numbersToSeekFor[1] )
        {
          colors.Add(colorsToAssign[1]);


        }

        if(data[i] == numbersToSeekFor[2])
        {
          colors.Add(colorsToAssign[2]);


        }


    }

    return colors;
  }

实现这一目标的最干净的方法是什么?

感谢您的帮助

【问题讨论】:

  • 一方面说which will never have equal length似乎也很矛盾,但后来List&lt;int&gt; data which is of n length和List&lt;int&gt; numbersToSeekFor which is of n length,所以两者的长度n好像一样?

标签: c# list comparison


【解决方案1】:

好吧,您可以使用 LINQ .Where 和 .Select 方法的组合:

public static List<Color> Foo3(List<int> data, List<int> numbersToSeekFor, List<Color> colorsToAssign)
{
    if (data?.Any() != true || numbersToSeekFor?.Any() != true || colorsToAssign?.Count != data.Count)
    {
        return new List<Color>();
    }

    List<Color> colors = data
                         .Select(d => numbersToSeekFor.IndexOf(d))
                         .Where(i => i > -1 && i < colorsToAssign.Count)
                         .Select(i => colorsToAssign[i])
                         .ToList();
    return colors;
}

【讨论】:

  • Fabjan 感谢您的回复。抱歉,我没有在帖子中明确这一点,但颜色的长度必须与数据相同。目前,您的示例颜色只有 2 个元素。我相信这是因为 i
  • @Nicholas 我已根据您的需要更改了代码。起初我以为我们是在严格按索引比较值...
【解决方案2】:

如果我理解正确,numbersToSeekFor 用于将数据中的数字映射到 colorsToAssign 中的索引。所以也许先转换成字典是个好主意:

var mapNumberToIndex = new Dictionary<int, int>();
for (var i = 0; i < numbersToSeekFor.Count; i++)
    mapNumberToIndex.Add(numbersToSeekFor[i], i);

那么你可以简单地使用

colors.Add(mapNumberToIndex[data[i]]);

在你的循环中

【讨论】:

    【解决方案3】:

    您可以使用字典将值映射到颜色上,而无需传入所有不同值的单独列表:

        public static List<Color> AssignColours(List<int> data, List<Color> coloursToAssign)
        {
            var result = new List<Color>();
            var map    = new Dictionary<int, Color>();
            int n      = 0;
    
            foreach (var datum in data)
            {
                if (!map.TryGetValue(datum, out var colour))
                {
                    // Next line will throw exception if number of distinct numbers
                    // is greater than length of coloursToAssign.
    
                    colour = coloursToAssign[n++];
                    map[datum] = colour;
                }
    
                result.Add(colour);
            }
    
            return result;
        }
    

    此代码假定不同值的计数为 coloursToAssign 的长度,否则注释行会出现异常。

    或者(如果您多次调用它会更有效)您可以像这样预先计算地图:

    public static Dictionary<int, Color> MapColours(List<int> numbersToSeekFor, List<Color> coloursToAssign)
    {
        var map = new Dictionary<int, Color>();
    
        for (int i = 0; i < numbersToSeekFor.Count; ++i)
            map[numbersToSeekFor[i]] = coloursToAssign[i];
    
        return map;
    }
    

    然后像这样使用它:

    var map = MapColours(numbersToSeekFor, coloursToAssign);
    
    ...
    
    var colourToUse = map[data[someIndex]];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-16
      • 1970-01-01
      相关资源
      最近更新 更多