1

我有一个程序可以根据文本文件的内容生成 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

4 回答 4

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 ...
于 2013-07-24T06:58:20.037 回答
1

就像是:

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

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

此时不会评估查询。做一个.ToList()or.ToArray()让它发生在 上g

于 2013-07-24T07:05:16.223 回答
0

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

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

只需稍微修改它以使用“Hello”而不是“1x Hello”。

于 2013-07-24T06:56:31.930 回答
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));

希望能帮助到你。

于 2013-07-24T07:11:46.520 回答