我有一个对象列表,包含一个字符串,或字符串列表。我正在尝试提取一个"扁平"字符串列表。我有一个解决方案,但我正在努力寻找一个更好的方法。
下面是创建输入的简单步骤:class Foo
{
public bool IsArray { get; set; }
public object Values { get; set; }
} //...
var innerList = new List<string> {"Inner111", "Inner222"}
var fooList = new List<Foo>();
fooList.Add(new Foo { IsArray = false, Values = "simpleVaue" });
fooList.Add(new Foo { IsArray = false, Values = innerList });
我想要的结果:
["simpleVale","Inner111","Inner222"]
我尝试了几种不同的Linq方法,SelectMany, Aggregate,Select…
var outputListWithWastefulListCreation =
fooList.SelectMany<Foo, string>(z =>
{
if (!z.IsArray)
{
var wastefulList = new List<string> {z.Values.ToString()};
return wastefulList;
}
var listObject = (IEnumerable<string>) z.Values;
return listObject;
});
再一次,我期望的结果:
["simpleVale","Inner111","Inner222"]
我相信一定有更好的方法?
您可以尝试将单个值转换为SelectMany
中的集合:
var result = fooList
.SelectMany(item => item.IsArray
? item.Values as List<String>
: new List<String>() {item.Values as String});
另一个更好的可能性是实现IEnumerable<String> GetValues()' method in the
foo ' class:
class Foo
{
public bool IsArray { get; set; }
public object Values { get; set; }
public IEnumerable<String> GetValues()
{
if (null == values)
yield break;
List<String> list = Values as List<String>;
if (list != null)
foreach (var item in list)
yield return item;
else
yield return Values as String;
}
}
所以你可以直接写
var result = fooList
.SelectMany(item => item.GetValues());
尝试如下:
fooList.SelectMany<Foo, string>(z => z.IsArray ? ((List<string>) z.Values) : new List<string>() {(string) z.Values});
但首先要做的是考虑您的Foo类设计是否ok,或者您可以更改它(可能为一个字符串和列表使用两个不同的类)以避免此类棘手的问题。