我有一个List
double 值,其中一些元素是 NaN。我想将此列表转换为使用 NaN 作为分隔符的多个双精度列表。例子:
List<double> values = new List<double>
{ 1.2, 2.2, 3.2, Double.NaN, 2.2, 2.3, Double.NaN, 4.1, 4.2, 4.3 };
List<List<double>> result = values.SomeLinqOperator....
没有内置任何东西,但你可以写一个:
public static IEnumerable<List<T>> SplitBy<T>(
this IEnumerable<T> source, T delimiter)
{
List<T> buffer = new List<T>();
var comparer = EqualityComparer<T>.Default;
foreach (var item in source)
{
if (comparer.Equals(item, delimiter))
{
yield return buffer;
buffer = new List<T>();
}
else
{
buffer.Add(item);
}
}
yield return buffer;
}
static void Main()
{
List<double> values = new List<double>
{1.2,2.2,3.2,double.NaN,2.2,2.3,double.NaN,4.1,4.2,4.3 };
List<List<double>> result = values.SplitBy(double.NaN).ToList();
}
List<List<double>> result = values.GroupDelimited(x => x == double.NaN)
.Select(g => g.ToList())
.ToList();
从这里使用GroupDelimited 扩展方法。
如果您有两个double.NaN
值,或者在输入的开头或结尾有一个值,这将包括空列表:
List<List<double>> result = new List<List<double>>();
List<double> current = new List<double>();
foreach (double d in values)
{
if (d == double.NaN)
{
result.Add(current);
current = new List<double>();
}
else
{
current.Add(d);
}
}
result.Add(current);
这是一个更简单的(我认为)。
public static IEnumerable<IEnumerable<T>> SplitBy<T>(this IEnumerable<T> source, T delimiter)
{
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (IEnumerable<T> s = source; s.Any(); s = s.SkipWhile(s2 => !comparer.Equals(s2, delimiter)).Skip(1))
yield return s.TakeWhile(s2 => !comparer.Equals(s2, delimiter));
}