我如何计算列表中的重复项并更改项值

时间:2013-07-24 06:47:43

标签: c#

我有一个程序,根据文本文件的内容生成3个列表。现在我想查看一个列表,如果其中有一个项目不止一次,我想将值更改为“列表x项目中的数字”并从列表中删除重复项。

以下是我用来打开文件并将其拆分为列表的代码:

    private void open_Click(object sender, EventArgs e)
    {
        if (inputFile.ShowDialog() == DialogResult.OK)
        {
         var reader = new StreamReader(File.OpenRead(inputFile.FileName));
         while (!reader.EndOfStream)
             {
                 string line = reader.ReadLine();
                 if (string.IsNullOrEmpty(line)) continue;
                 if (line.StartsWith("#main"))
                 {
                     deck = "main";
                 }
                 if (deck == "main")
                 {
                     if (!line.StartsWith("#"))
                     {
                         int cardid = Convert.ToInt32(line.Substring(0));
                         MainDeck.Items.Add(Program.CardData[cardid].Name);
                     }
                 }
                 if (line.StartsWith("#extra"))
                 {
                     deck = "extra";
                 }
                 if (deck == "extra")
                 {
                     if (!line.StartsWith("#extra") && !line.StartsWith("!side"))
                     {
                         int cardid = Convert.ToInt32(line.Substring(0));
                         ExtraDeck.Items.Add(Program.CardData[cardid].Name);
                     }
                 }

                 if (line.StartsWith("!side"))
                 {
                     deck = "side";
                 }
                 if (deck == "side")
                 {
                     if (!line.StartsWith("!side"))
                     {
                         int cardid = Convert.ToInt32(line.Substring(0));
                         SideDeck.Items.Add(Program.CardData[cardid].Name);
                     }
                 }
            }
         reader.Close();
         GenerateCode();
        }
    }

换句话说,项目"hello"在列表中有3次:我想将其更改为仅在列表中一次并说出"3x hello"

4 个答案:

答案 0 :(得分:3)

使用Enumerable.Distinct删除重复项:

MainDeck = MainDeck.Distinct().ToList();
ExtraDeck = ExtraDeck.Distinct().ToList();
SideDeck = SideDeck.Distinct().ToList();

如果您想先计算重复项:

int mainDeckDups = MainDeck.Count - MainDeck.Distinct().Count();
int extraDeckDups = ExtraDeck.Count - ExtraDeck.Distinct().Count();
int sideDeckDups = SideDeck.Count - SideDeck.Distinct().Count();

如果您真的想要显示项目在列表中的次数,可以使用Enumerable.GroupBy,例如:

var mainDeckGroups = MainDeck.GroupBy(s => s)
    .Select(g => new { Item = g.Key, Count = g.Count() })
    .Where(x => x.Count > 1)
    .OrderByDescending(x => x.Count);
foreach (var dup in mainDeckGroups)
    Console.WriteLine("{0}x {1}", dup.Count, dup.Item);
// other lists ...

答案 1 :(得分:1)

类似的东西:

var g = MainDeck.Items.GroupBy(i => i).Select(x => x.Count() +"x " + x.Key);

如果您只想在那里计算单词“main”,可以将其过滤掉。对其他列表也一样。

此时不评估查询。执行.ToList().ToArray()以便在g上发生这种情况。

答案 2 :(得分:0)

如果要保留列表中项目的顺序(假设列表包含可能的重复项)

var data = list.Select(r => result.Count(i => i == r) + "x " + r).ToList();

并稍微修改它以获得“Hello”而不是“1x Hello”。

答案 3 :(得分:0)

您也可以尝试一下。

var list = new List<string> { "Hello", "World", "Hello", "Great", "World" };

var query = list.GroupBy(s => s)
        .Select(g => new { Value = g.Key, Count = g.Count() });

然后,

var resultList = query.Select(result => string.Format("{0}x {1}", result.Count, result.Value)).ToList();

或以上代码可以替换如下,以便更清晰

foreach (var result in query)
    resultList.Add(string.Format("{0}x {1}", result.Count, result.Value));

希望它有所帮助。