如果我有一个布尔列表,我如何转换成一个整数列表(或任何其他IEnnumerable<int>
)整数,其中每个整数代表使用LINQ的每个布尔字符串的长度?
例如,{true, true, false, false, true, true, true}
将成为{2, 3}
,因为true
的第一次运行为2长,第二次运行为3长。或者我必须回去做foreach循环吗?
我对错误值的数量不感兴趣,它们只是重要的,因为它们分隔了真值的运行。
因此{true, true, true, false, true, true, true, true, false, false, true, true, true}
将成为{3, 4, 3}
答案 0 :(得分:7)
这样的事情:
public static class IEnumerableExt
{
public static IEnumerable<int> ConsecutiveTrues(this IEnumerable<bool> bools)
{
var flag=false;
int count=0;
foreach(var b in bools)
{
if (b)
{
count++;
} else if (flag)
{
yield return count;
count=0;
}
flag=b;
}
if (flag)
yield return count;
}
}
然后用作:
void Main()
{
var bools=new bool[]{true, true, false, false, true, true, true};
var results=bools.ConsecutiveTrues();
}
使用纯LINQ方式(主要来自https://stackoverflow.com/a/27574266/856353):
var str = new bool[]{true, true, true, false, true, true, true, true, false, false, true, true, true};
// Retain a horrid mutable sequence which tracks consecutive characters
var sequence = 0;
var grps = str
.Zip((str.Concat(new bool[]{str.Last()})).Skip(1),
(prev, current) => new { prev, current })
.GroupBy(p => new {
Ch = p.prev,
Sequence = p.current == p.prev
? sequence
: sequence++})
.Where(l=>l.Key.Ch==true)
.Select(l=>l.Count());
答案 1 :(得分:1)
没有糟糕的LINQ,只是糟糕的想法:)。 它可以很好地完成LINQ,但仍然可以知道它的作用。
嗯,我希望如此:)。
List<bool> lst = new List<bool>() { true, true, true, false, true, true,
true, true, false, false, true, true,
true };
var bb =
lst
.Aggregate(new List<int>(), (acc, element) =>
{
if (element == true && acc.Count < 1) acc.Add(1);
else if (element == true && acc.Count > 0) acc[acc.Count - 1]++;
else if(acc.Count > 0 && acc[acc.Count - 1] > 0) acc.Add(0);
return acc;
}, acc =>
{
if (acc.Count > 0 && acc[acc.Count - 1] == 0)
{
acc.RemoveAt(acc.Count - 1);
}
return acc;
});
//{3, 4, 3}
答案 2 :(得分:0)
前段时间我制作了一个寻找连续元素的通用版本。 它适用于任何实现IComparable的东西,并且可以选择,感兴趣的元素是什么。
只是一种思考的食物:)。
public
static
class IEnumerableExtensions
{
public
static
IEnumerable<int> CountConsecutiveElements<TElement>(this IEnumerable<TElement> ie,
TElement consecutive_element)
where TElement: IComparable<TElement>
{
using(var en = ie.GetEnumerator())
{
int i = 0;
while (en.MoveNext())
{
if (en.Current.CompareTo(consecutive_element) == 0) i++;
else if (i > 0)
{
yield return i;
i = 0;
}
}
if (i > 0) yield return i;
}
}
}
然后使用很简单:
List<bool> lst = new List<bool>() { true, true, true, false, true, true,
true, true, false, false, true, true,
true };
//var rslt = lst.CountConsecutiveElements(true).ToList();
//there is no need for .ToList()
var rslt = lst.CountConsecutiveElements(true);
//{3, 4, 3}