在列表中添加和计数项目

本文关键字:项目 添加 列表 | 更新日期: 2023-09-27 18:05:17

假设我有一个像这样的文件:

R34     128590    -74.498   109.728  0    0805_7  
R33     128590    -74.498   112.014  0    0805_7  
R15     128588    -68.910   127.254  0    0805_7  
R32     128587    -65.354   115.189  0    0805_7  
R35     128587    -65.354   117.348  0    0805_7  
R38     128590    -65.354   119.507  0    0805_7  

我想要做的是将第二列添加到列表中,并让计数器计算该项目出现的次数,然后输出该数字和该数字的计数量。

是否有一种方法来做到这一点使用列表?如果是这样,我该怎么做呢?

我试过乱弄东西,这就是我要去的地方。但是它不能正常工作

int lineCount = 1;
int itemCounter = 0;
foreach (var item in aListBox.Items)
{
    // Creates a string of the items in the ListBox.
    var newItems = item.ToString();
    // Replaces any multiple spaces (tabs) with a single space.
    newItems = Regex.Replace(newItems, @"'s+", " ");
    // Splits each line by spaces.
    var eachItem = newItems.Split(' ');
    ### 
    ### HERE is where I need help ###
    ### 
    List<string> partList = new List<string>();
    partList.Add(eachItem[1]);
    if (partList.Contains(eachItem[1]))
        itemCounter++;
    else 
        partList.Add(eachItem[1]);
    sw.WriteLine(lineCount + ": "+ partList + ": " + itemCounter);
    lineCount++;
}

SO对于上面的例子,它将输出如下:

1: 128590: 3        #lineCount, partList, itemCounter
2: 128588: 1
3: 128587: 2

谁能帮我弄清楚如何正确地做这件事?

在列表中添加和计数项目

使用linq与count和group by(参见count - Grouped一节)。

在foreach循环外创建partList,并将每个项目添加到循环内,以便它包含所有元素:

List<string> partList = new List<string>();
foreach (var item in aListBox.Items)
{
    //regex stuff here...
    partList.Add(eachItem[1]);
} 

(在您的示例中- {128590, 128590, 128588, 128587, 128587, 128590})
然后使用LINQ输出结果-

var elementsWithCounts = from p in partList
     group p by p into g
     select new { Item = g.Key, Count = g.Count()};

我会使用Linq查询或Dictionary

比如

    List<string> items = new List<string>{"128590", "128590", "128588", "128587", "128587", "128590"};
    Dictionary<string,int> result = new Dictionary<string,int>();
    foreach( int item in items )
    {
        if(result.ContainsKey(item) )
            result[item]++;
        else
            result.Add(item,1);
    }
    foreach( var item in result )
        Console.Out.WriteLine( item.Key + ":" + item.Value );

一旦你有了按空格分割的项目,我假设你有一个字符串数组看起来像这样:

[0] = "R34"
[1] = "128590"
[2] = "-74.498"
[3] = "109.728"
[4] = "0"
[5] = "0805_7"

您可以简单地通过Group By操作来执行此操作。

var items = aListBox.Items.Select(x => /* Split Code Here and Take Element 1 */).GroupBy(x => x);
foreach(var set in items)
{
     Console.WriteLine(set.Key + " appeared " + set.Count() + " times.");
}

基本上,你试图通过迭代一次来做到这一点,这并不会真正起作用,你将不得不迭代两次,否则你将在每次循环foreach时都输出一个输出,即使你是准确的,你也将每次输出一个新行。如果您确实需要使用List而不是键字典或哈希表(key = number, value = count),那么您需要首先构建列表,然后汇总列表。您可以使用LINQ Group By(这有点简洁),或者创建一个与您已有的功能类似的函数。如果你想学习概念,看看下面的代码,它可能更简洁,但这应该是相当容易阅读的。

List<string> partList = new List<string>();
List<string> displayedNumbers = new List<int>();
// Build the original list first.
foreach (var item in aListBox.Items)
{
    // Creates a string of the items in the ListBox.
    var newItems = item.ToString();
    // Replaces any multiple spaces (tabs) with a single space.
    newItems = Regex.Replace(newItems, @"'s+", " ");
    // Splits each line by spaces.
    var eachItem = newItems.Split(' ');
    partList.Add(eachItem[1]);
}
// Now run through that list and count how many times the same number occurs.
// You will need two loops for this since your list is a single dimension collection.
foreach(var number in partList)
{
  var innerList = partList;

  // set this to zero because we are going to find at least 1 duplicate.
  var count = 0;
  foreach(var additionalNumber in innerList)
  {
    if(additionalNumber == number)
     {
       // If we find anymore increase the count each time.
       count += 1;
     }
  }  
   // Now we have the full count of duplicates of the outer number in the list.
   // If it has NOT been displayed, display it.
   if(!displayedNumbers.Contains(number))
    { 
      sw.WriteLine(partList + ": " + count);
      displayedNumbers.Add(number);
    }
}

使用哈希表而不是列表。您可以将密钥保存为128590,…这个值是它出现的次数。在插入新值之前,请使用Contains操作检查该值是否已经存在于哈希表中,以及该值是否增加。

我认为最大的问题是从文本字段的原始行到单个值。我的猜测是,这是一个以制表符分隔的文件,具有已知的常量列数,在这种情况下,可以使用String.Split()分隔子字符串。一旦将字符串分开,就可以很容易地使用LINQ计算相应列的实例。给定文件的行列表或集合:

var histogram = myListOfLines
    //Split each string along spaces or tabs, and discard any zero-length strings
    //caused by multiple adjacent delimiters.
   .Select(s=>s.Split(new[]{''t',' '}, StringSplitOptions.RemoveEmptyEntries))
    //Optional; turn the array of strings produced by Split() into an anonymous type
   .Select(a=>new{Col1=a[0], Col2=a[1], Col3=a[2], Col4=a[3], Col5=a[4]})
    //Group based on the values of the second column.
   .GroupBy(x=>x.Col2)
    //Then, out of the grouped collection, get the count for each unique value of Col2.
   .Select(gx=>new{gx.Key, gx.Count()});