从c#中的一组重复单词列表中形成不同单词的列表

时间:2014-08-07 10:38:05

标签: c# linq

我有一个模特:

 public class CompanyModel1
    {
        public string compnName1 { get; set; }
        public string compnKeyProcesses1 { get; set; }
    }

然后我形成一个列表:

List<CompanyModel1> companies1 = new List<CompanyModel1>();

如果我访问其值:

var newpairs = companies1.Select(x => new { Name = x.compnName1, Processes = x.compnKeyProcesses1 });
            foreach (var item in newpairs)
            {

                string CName = item.Name;
                Process = item.Processes;
            }

我会得到如下价值:

CName = "name1"
Process = "Casting, Casting, Casting, Welding, brazing & soldering"

CName = "name2"
Process = "Casting, Welding, Casting, Forming & Forging, Moulding"

etc.

现在我想要形成一个不同的进程和计数数量的列表,每个进程有多少时间用不同的名称。

例如,如上所述,我必须形成如下列表:

"Casting, Welding, brazing & soldering, Forming & Forging, Moulding"

如果算上,将有:5个不同的过程;每个名字的频率:

"Casting" appears in 2 names
"Welding" appears in 2 names
"brazing & soldering" appears in 1 names
"Forming & Forging" appears in 1 names
"Moulding" appears in 1 names

我在想Linq可以帮助解决这个问题,可能是这样的:

var list= Process
    .SelectMany(u => u.Split(new string[] { ", " }, StringSplitOptions.None))
    .GroupBy(s => s)
    .ToDictionary(g => g.Key, g => g.Count());

var numberOfProcess = list.Count;

var numberOfNameWithProcessOne = frequency["Process1"];

但是我怎么能把它放在foreach循环中并申请我拥有的所有名称和流程并获得我想要的结果?

1 个答案:

答案 0 :(得分:3)

var processes = companies1.SelectMany(
c => c.compnKeyProcesses1.Split(new char[] { ',' }).Select(s => s.Trim()).Distinct())
.GroupBy(s => s).ToDictionary(g => g.Key, g => g.Count());
foreach(var process in processes)
{
    Console.WriteLine("\"{0}\" appears in {1} names", process.Key, process.Value);
}

这将仅从每个公司中选择 distinct 进程,然后使用SelectMany创建所有主列表,以便为每个进程存储正确数量的唯一出现次数。然后我们只计算最终列表中每个进程的出现次数,并将它们放入process =&gt; count的字典中。

编辑:

这是另一种将数据分组到字典中的解决方案,以允许显示每个进程的关联公司。该词典来自流程名称 - &gt;公司名称清单。

Func<string, IEnumerable<string>> stringToListConverter = s => s.Split(new char[] { ','     }).Select(ss => ss.Trim());
var companiesDict = companies1.ToDictionary(c => c.compnName1, c => stringToListConverter(c.compnKeyProcesses1).Distinct());
var processesAll = companies1.SelectMany(c => stringToListConverter(c.compnKeyProcesses1)).Distinct();
var processesToNames = processesAll.ToDictionary(s => s, s => companiesDict.Where(d => d.Value.Contains(s)).Select(d => d.Key).ToList());
foreach(var processToName in processesToNames)
{
     List<string> companyNames = processToName.Value;
     Console.WriteLine("\"{0}\" appears in {1} names : {2}", processToName.Key, companyNames.Count, String.Join(", ", companyNames));
}

我保存了stringToListConverter Func委托,将进程字符串转换为列表,并在两个查询中使用了该委托。

如果CompanyModel1类将compnKeyProcesses1字段存储为List<string>而不是仅存储一个大string,则此查询将更具可读性。这样你就可以立即查询列表,而不是每次都进行拆分,选择和修剪。