我有一个模特:
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循环中并申请我拥有的所有名称和流程并获得我想要的结果?
答案 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
,则此查询将更具可读性。这样你就可以立即查询列表,而不是每次都进行拆分,选择和修剪。