这不是一个家庭作业问题。如有必要,请随时推荐一个更好的地方发布。
鉴于以下数据结构:
class Thing
{
public Thing()
{
this.Things = new List<Thing>();
}
public string First { get; set; }
public string Group { get; set; }
public List<Thing> Things { get; set; }
}
以下数据:
var data = new List<Thing>
{
new Thing { First = "Alex", Group = "Sams" },
new Thing { First = "John", Group = "Sams" },
new Thing { First = "", Group = "Sams" },
new Thing { First = "Sue", Group = "Freds" },
};
将LINQiest重新塑造成如下所示的List的方法是什么:
First = "", Group = Sams
First = Alex, Group = Sams
First = John, Group = Sams
First = Sue, Group = Freds
有些注意事项:
此示例显示了所需的结果:
var result = data.Where(p => p.First == "").Select(p =>
{
p.Things = data.Where(f => f.Group == p.Group).ToList();
return p;
}).ToList();
result.AddRange(data.Except(result.SelectMany(f => f.Things)).ToList());
这也达到了预期的效果,但感觉有点长......
var result = data
.GroupBy(p => p.Group)
.SelectMany(p => p.Where(f => f.First == "" || p.Count() == 1))
.Select(p => new Thing { First = p.First, Group = p.Group, Things = data
.Where(f => f.Group == p.Group && f.First != "" && p.First != f.First).ToList() });
答案 0 :(得分:2)
这似乎很不错:
var result =
data
.Where(p => p.First != "")
.GroupBy(p => p.Group)
.Select(gps =>
gps.Count() == 1
? gps.First()
: new Thing()
{
First = "",
Group = gps.Key,
Things = gps.ToList(),
})
.ToList();
这基本上忽略了First == ""
的所有现有事物,然后按Group
对所有剩余事物进行分组。然后,它会使用新父级重建列表,其中组具有多个内容。
在有“没有子女”的“父”对象的情况下,这是另一种更强大的选择:
var result2 =
data
.GroupBy(p => p.Group)
.Select(gps =>
gps.Count() == 1
? gps.First()
: new Thing()
{
First = "",
Group = gps.Key,
Things =
gps
.Where(p => p.First != "")
.ToList(),
})
.ToList();
答案 1 :(得分:0)
功能无需错误检查或其他考虑因素。
static void Main(string[] args)
{
var data = new List<Thing> { new Thing { First = "Alex", Group = "Sams" }, new Thing { First = "John", Group = "Sams" }, new Thing { First = "", Group = "Sams" }, new Thing { First = "Sue", Group = "Freds" } };
var results = from item in data
group item by item.Group into g
select g;
List<Thing> list = new List<Thing>();
foreach (var item in results)
{
if (item.Count() > 1)
{
Thing parent = item.Where(x => String.IsNullOrEmpty(x.First)).First();
parent.First = "";
parent.Group = item.First().Group;
parent.Things = item.Where(x => x != parent).ToList();
list.Add(parent);
}
else
{
list.Add(item.First());
}
}
}
答案 2 :(得分:0)
一个陈述是......由于多个枚举而更有效率......
var unflattenedList = data.GroupBy(thing => thing.Group, thing => thing,
(key, things) => new Thing()
{
First = things.Count() == 1 ? things.First().First : string.Empty,
Group = key,
Things = things.Count() == 1 ? null :
things.Where(t => t.First != string.Empty).ToList(),
});
修改强> 以下是我将使用的...因为这消除了上述解决方案的多个枚举问题。
你的LINQ是这样的......
var unflattenedList = data.GroupBy(thing => thing.Group, thing => thing, GetThing);
你的返回新东西的方法就在这里......
private static Thing GetThing(string key, IEnumerable<Thing> things)
{
var thingList = things.ToList();
return new Thing()
{
First = thingList.Count() == 1 ? thingList.First().First : string.Empty,
Group = key,
Things = thingList.Count() == 1 ? null :
thingList.Where(t => t.First != string.Empty).ToList(),
};
}