LINB中的GroupBy字符串和计数

时间:2009-02-12 06:09:46

标签: linq

我有一个收藏品。 coll有字符串:

Location="Theater=1, Name=regal, Area=Area1"

Location="Theater=34, Name=Karm, Area=Area4445"

等等。我必须从字符串中提取名称位。例如,在这里我必须提取文本'regal'并对查询进行分组。然后将结果显示为

Name=regal Count 33
Name=Karm  Count 22

我正在努力解决这个问题:

Collection.Location.GroupBy(????);(这里添加什么)

哪种方法最简短,最精确?

3 个答案:

答案 0 :(得分:10)

另一种Linq + Regex方法:

string[] Location = {
                        "Theater=2, Name=regal, Area=Area1",
                        "Theater=2, Name=regal, Area=Area1",
                        "Theater=34, Name=Karm, Area=Area4445"
                    };

var test = Location.Select(
                            x => Regex.Match(x, "^.*Name=(.*),.*$")
                                      .Groups[1].Value)
                   .GroupBy(x => x)
                   .Select(x=> new {Name = x.Key, Count = x.Count()});

查询测试字符串的结果

答案 1 :(得分:1)

提取完字符串后,只需将其分组并计算结果:

var query = from location in locations
            let name = ExtractNameFromLocation(location)
            group 1 by name in grouped
            select new { Name=grouped.Key, Count=grouped.Count() };
但是,这并不是特别有效。它必须在进行任何计数之前进行所有分组。有关LINQ to Objects的扩展方法,请查看this VJ article, 和this one about Push LINQ这是一种看待LINQ的方式。

编辑:ExtractNameFromLocation将是从other question的答案中获取的代码,例如

public static string ExtractNameFromLocation(string location)
{
    var name = (from part in location.Split(',')
                let pair = part.Split('=')
                where pair[0].Trim() == "Name"
                select pair[1].Trim()).FirstOrDefault();
    return name;
}

答案 2 :(得分:1)

这是另一个带有工作示例的LINQ替代解决方案。

static void Main(string[] args)
{
    System.Collections.Generic.List<string> l = new List<string>();
    l.Add("Theater=1, Name=regal, Area=Area"); l.Add("Theater=34, Name=Karm, Area=Area4445");

    foreach (IGrouping<string, string> g in l.GroupBy(r => extractName(r)))
    {
        Console.WriteLine( string.Format("Name= {0} Count {1}", g.Key, g.Count())  );
    }
}
private static string extractName(string dirty)
{
    System.Text.RegularExpressions.Match m =
        System.Text.RegularExpressions.Regex.Match(
        dirty, @"(?<=Name=)[a-zA-Z0-9_ ]+(?=,)");

    return m.Success ? m.Value : "";
}