【问题标题】:Finding duplicates in an array and its index number在数组及其索引号中查找重复项
【发布时间】:2014-11-21 16:23:15
【问题描述】:

使用 vs 2010 C#

我有以下数组,我正在尝试查找是否有重复项 在数组中。我也想知道他们的索引

red 
red
Grey
Grey
red
blue
blue
Green
White
Grey

我想得到数组每个值的重复计数,例如:

red    Count=2  index=0 (contain the duplicate cluster start index)
Grey   Count=2  index=2
red    Count=1  index=4
blue   Count=2  index=5
Green  Count=1  index=6
White  Count=1  index=7
Grey   Count=1  index=8

帮我修正下面的语法以完全填充上述结果

var result = from p in a //a is the list
                         group p by p into g
                         select new { value=g.Key,count=g.Count()};

【问题讨论】:

  • 该代码会产生什么?您希望看到它如何改变?
  • @shamim - 你有机会看看我的答案吗?

标签: c# arrays linq


【解决方案1】:
var dupl = new Dictionary<string, List<int>>();
var d = a.Distinct();
for (int i = 0; i < d.Count; ++i)
{
   int match = 0;
   for (int j = 0; j < a.Count; ++j)
   {
       if (a[j] == d[i])
       {
          ++match;
          if (++match > 1)
          {
              if (dupl.ContainsKey(d[i])) dupl[d[i]].Add(j);
              else
              {
                 dupl.Add(d[i], new List<int>());
                 dupl[d[i]].Add(j);
              }
          }
       }
   }
}

这将为您生成一个字典,其键为重复字符串(存在 > 1),其值为 a 列表中的索引列表。

【讨论】:

    【解决方案2】:

    你可以使用GroupAdjacent扩展方法写here。从此question 获取此参考。您的查询将变得非常简单:-

    var result = colors.Select((v, i) => new { Value = v, Index = i })
                                   .GroupAdjacent(x => x.Value)
                                   .Select(x => new
                                   {
                                       Color = x.Key,
                                       Count = x.Count(),
                                       Index = x.First().Index
                                   });
    

    完整的工作小提琴Here

    【讨论】:

    • Rahul Singh,感谢您的回复。您的语法令人难以置信,但我对扩展方法过程不感兴趣。再次感谢您的回复
    【解决方案3】:

    这是最后的工作:

    namespace ConsoleApplication1
    {
        using System;
        using System.Linq;
    
        class Program
        {
            static void Main(string[] args)
            {
                var AS = new[] { "red", "red", "Grey", "Grey", "blue" };
                var zippedList = AS.Zip(Enumerable.Range(0, AS.Length), (s, i) => new { s, i });
    
                var finalResult =
                    from a in zippedList
                    group a by a.s into g
                    select new { key = g.Key, result = new { list = g.Select(o => o.i).ToList(), count = g.Count() } };
                foreach (var item in finalResult)
                {
                    Console.WriteLine(item.key);
                    Console.WriteLine(item.result.count);
                    Console.WriteLine(item.result.list);
                }
                Console.ReadLine();
            }
        }
    }
    

    类似这样的工作

    from a in AS
    from b in Enumerable.Range(0,AS.Conunt()-1)
    into (a,b)
    group by a
    

    然后您可以通过计算每个组的长度轻松地将计数添加到结果中。

    我没有 Visual Studio,也没有很好的记忆力来记住 LINQ,但它已经足够开始了。

    【讨论】:

    • 对于那些投了反对票的人,我只是想表明代码的函数式风格比命令式风格简单得多。
    • 这不是我的反对意见,但您的解决方案没有产生作者在他的示例中展示的内容。在数组末尾添加另一个“红色”,您将获得相同数量的结果 (3)。但他只想对连续的项目进行分组。在他想要的结果中,他有两次“红”
    猜你喜欢
    • 1970-01-01
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多