C# 从文本框中输入的字符串中读取所有字符,而不重复和计数每个字符

C# 从文本框中输入的字符串中读取所有字符,而不重复和计数每个字符,c#,string,C#,String,我想从文本框中输入的字符串中读取所有字符,不重复每个字符的计数,然后使用C、Asp.Net将这些值存储到两个网格列中 我叫乔 然后将它们存储到栅格视图列中您可以使用LINQ运算符GroupBy: string str = ":My name is Joe"; var result = str.Where(c => char.IsLetter(c)). GroupBy(c => char.ToLower(c)). S

我想从文本框中输入的字符串中读取所有字符,不重复每个字符的计数,然后使用C、Asp.Net将这些值存储到两个网格列中

我叫乔


然后将它们存储到栅格视图列中

您可以使用LINQ运算符GroupBy:

string str = ":My name is Joe";

var result = str.Where(c => char.IsLetter(c)).
                 GroupBy(c => char.ToLower(c)).
                 Select(gr => new { Character = gr.Key, Count = gr.Count()}).
                 ToList();
这将为您提供一个包含字符和计数字段的对象列表

编辑:我添加了Where子句以过滤掉非字母字符。还增加了案例不敏感

现在,您必须使用结果列表作为网格的绑定源。我对ASP.NET绑定过程的理解有些生疏。您可能需要创建具有字符和计数属性的某些类的对象,而不是无法绑定到字段的匿名对象

string input = "My name is Joe";

var result = from c in input.ToCharArray()
             where !Char.IsWhiteSpace(c)
             group c by Char.ToLower(c)
             into g
             select new Tuple<string, int>(g.Key.ToString(),g.Count());

int total = result.Select(o => o.Item2).Aggregate((i, j) => i + j);

List<Tuple<string, int>> tuples = result.ToList();

tuples.Add(new Tuple<string, int>("Total", total));

您可以将元组列表数据绑定到数据网格:

如果您不喜欢LINQ解决方案,下面介绍如何使用foreach循环:

string str = ":My name is Joe";

var letterDictionary = new Dictionary<char,int>();

foreach (char c in str) {
    // Filtering non-letter characters
    if (!char.IsLetter(c))
        continue;

    // We use lowercase letter as a comparison key
    // so "M" and "m" are considered the same characters
    char key = char.ToLower(c);

    // Now we try to get the number of times we met
    // this key already.
    // TryGetValue method will only affect charCount variable
    // if there is already a dictionary entry with this key,
    // otherwise its value will be set to default (zero)
    int charCount;
    letterDictionary.TryGetValue(key, out charCount);

    // Either way, we now have to increment the charCount value
    // for our character and put it into dictionary
    letterDictionary[key] = charCount + 1;  
}

foreach (var kvp in letterDictionary) {
    Console.WriteLine("{0}: {1}", kvp.Key, kvp.Value);
}

现在,您必须使用其他答案中的一些技巧,将结果转换为可以绑定到datagrid的值列表。

我尝试了简单的控制台应用程序。希望这对您有所帮助。。 你可以在网上查看这个

结果如下:


在使用GroupBy运算符之前,您可能必须转换字符串字符数组?@AB Kolan:您不需要,您可以枚举字符串中的多个字符object@AB科兰:没问题,我不久前自己就知道了。我觉得它很整洁though@Dyppl奇怪的是,LINQPad为什么抱怨它:/@Dyppl LINQPad也没有在自动完成中显示GroupBy,用字符串类型存储count是怎么回事?它需要额外的强制转换,我看不到任何好处,DataGrid应该足够聪明来处理int值
string str = ":My name is Joe";

var letterDictionary = new Dictionary<char,int>();

foreach (char c in str) {
    // Filtering non-letter characters
    if (!char.IsLetter(c))
        continue;

    // We use lowercase letter as a comparison key
    // so "M" and "m" are considered the same characters
    char key = char.ToLower(c);

    // Now we try to get the number of times we met
    // this key already.
    // TryGetValue method will only affect charCount variable
    // if there is already a dictionary entry with this key,
    // otherwise its value will be set to default (zero)
    int charCount;
    letterDictionary.TryGetValue(key, out charCount);

    // Either way, we now have to increment the charCount value
    // for our character and put it into dictionary
    letterDictionary[key] = charCount + 1;  
}

foreach (var kvp in letterDictionary) {
    Console.WriteLine("{0}: {1}", kvp.Key, kvp.Value);
}
m: 2
y: 1
n: 1
a: 1
e: 2
i: 1
s: 1
j: 1
o: 1