我的情景如下:
我有以下数据 -
1, samename, Rock, New York, 12
2, samename, Jazz, Sydney, 12
3, samename, Rock, Sydney, 12
4, samename, Jazz, New York, 12
5, name3, Opera House, Sydney, 14
6, name3, Opera House, London, 14
7, name2, Emirates, London, 13
我想根据下面的GroupID输出扁平化
1, samename, {Rock,Jazz}, {New York,Sydney}, 12
5, name3, Opera House, {Sydney,London}, 14
7, name2, Emirates, London, 13
这是我继承的非常糟糕的设计 - 我试图让它变得更好......而不会破坏旧代码。
我认为答案与SelectMany有关 - 但我无法弄清楚语法 - 我尝试了几种不同的方法。
我的尝试解决方案 - 没有展平..
var q3 = Data.Where(b=>b.GroupID != null).GroupBy(x=> new { x.GroupID }, (key, group) => new
{
GroupID = key.GroupID,
Result = group.Select(g=> new
{
Type = g.Type,
Location = g.Location,
}).ToList()
});
答案 0 :(得分:5)
试试这个:
var answer = data.GroupBy(x => x.GroupID).Select(x => new {
ID = x.Min(y => y.ID),
Name = x.Select(y => y.Name).ToList(),
Type = x.Select(y => y.Type).ToList(),
Location = x.Select(y => y.Location).ToList(),
GroupID = x.Key
}).ToList();
答案 1 :(得分:2)
如果您有一系列具有内部元素序列的元素并且您想要将所有内部元素序列作为一个序列访问,则使用SelectMany。 SelectMany类似于以下代码:
loadScriptWithBluebird('jquery').then(function(){
//...
});
您想要相反:您希望将集合的多个元素组合成一个新序列。您的源中使用的所有名称应该生成一个包含多个字段的元素:
在您的示例中,Name对应于GroupId。你确定不能有两个带有“samename”和不同GroupId的元素吗?
第一步是使用GroupBy对具有相同名称的所有元素进行分组:
var result1 = sourceCollection.GroupBy(sourceElement => sourceElement.Name);
现在你有一组IGrouping项目,每个IGrouping项目都是一个具有相同名称的源元素序列,每个IGrouping项目都有一个包含这个相互名称的Key属性。
第二步是将每组中的所有元素转换为Id的序列,GroupId的Place和Sequences序列:
List<InnerClass> result = new List<InncerClass>()
foreach (var outerElement in outerSequence)
{
foreach (InnerClass innerElement in outerSequence.InnerSequence)
{
// note that InnserSequence is an IEnummerable in every InnerElement
result.Add(innerElement);
}
}
“从result1中的每个组中,创建一个具有属性Name的新对象,其中包含组的Key(这是所有groupElements中的公用名)。这个创建的对象也有一个属性Places,来自每个Place中的元素。每个创建对象也有一个属性Locations,它是......等。“
现在你所要做的就是从AllIds中获取最低值,以及来自Groupids的唯一值:
var result2 = result1.Select(group => new
{
Name = group.Key,
AllIds = group.Select(groupElement => groupElement.Id),
Places = group.Select(groupElement => groupElement.Place),
Locations = group.Select(groupElement => groupElement.Location),
GroupIds = group.Selelect(groupElement => groupElement.GroupId),
};
如果您不确定具有相同名称的所有元素是否具有相同的GroupId,请考虑按var result3 = result2.Select(item => new
{
Name = item.Name,
LowestId = item.AllIds.Orderby(id => id).First(),
Places = item.Places,
Locations = item.Locations,
OneAndOnlyGroupId = item.GroupId.First(),
};
分组,创建具有相同new {Name = sourceElement.Name, GrouId = sourceElement.GroupId)
的群组,或让您的最终{Name, GroupId}
成为如果OneAndOnlyGroupId
答案 2 :(得分:2)
试试这个:
var q = Data.Where(b => b.GroupID != null).GroupBy((x) => x.GroupID).Select((y) => new
{
GroupID = y.First().ID,
Name = string.Join(",", y.Select((k) => k.Name).Distinct()),
Type = string.Join(",", y.Select(( k) => k.Type).Distinct()),
Location = string.Join(",", y.Select(( k) => k.Location).Distinct()),
});
如果要动态加载列,请使用以下代码:
var q2 = Data.Where(b => b.GroupID != null).GroupBy((x) => x.GroupID).Select((y) => new
{
GroupID = y.First().ID,
result = DynamicGroup(y)
});
private static string DynamicGroup(IGrouping<string,DataD> y)
{
string result=null;
foreach (System.Reflection.PropertyInfo pInfo in typeof(DataD).GetProperties().Where(x=>x.Name!="GroupID" && x.Name!="ID"))
{
result += string.Format(" {0} ; ",string.Join(",", y.Select((k) => pInfo.GetValue(k, null)).Distinct()));
}
return result;
}