如何将布尔列表折叠为整数列表。
如何将布尔列表折叠为整数列表。
如果我有一个布尔值列表,我如何使用LINQ将其转换为一个整数列表(或任何其他IEnnumerable
),其中每个整数表示布尔字符串的长度?例如,{true, true, false, false, true, true, true}
将变为{2, 3}
,因为第一个连续的true
的长度是2,第二个连续的true
的长度是3。或者我必须回到使用for和foreach循环吗?我对false值的数量不感兴趣,它们只是重要的是因为它们分隔了连续的true值。所以{true, true, true, false, true, true, true, true, false, false, true, true, true}
将变为{3, 4, 3}
。
最近我做了一个通用版本,用于查找连续的元素。它适用于任何实现了IComparable接口的类型,并且可以选择感兴趣的元素。这只是一个思路。
下面是代码实现:
public static class IEnumerableExtensions { public static IEnumerableCountConsecutiveElements (this IEnumerable ie, TElement consecutive_element) where TElement: IComparable { 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; } } }
然后使用方法如下:
Listlst = new List () { true, true, true, false, true, true, true, true, false, false, true, true, true }; var rslt = lst.CountConsecutiveElements(true); // 输出:{3, 4, 3}
该问题的出现原因是需要将bool类型的列表转换为int类型的列表,其中int表示连续出现的true的次数。为了解决这个问题,创建了一个通用的扩展方法CountConsecutiveElements。该方法通过遍历列表,并使用IComparable接口进行比较,找到连续出现的元素,并返回它们的次数。最后,通过使用该方法,将bool类型的列表转换为int类型的列表。
如何将布尔值列表合并为整数列表
问题的原因是需要将一个布尔值列表合并为一个整数列表。具体的解决方法有两种。
第一种方法是创建一个名为IEnumerableExt的公共静态类,其中包含一个名为ConsecutiveTrues的方法。该方法使用迭代器实现,遍历布尔值列表,统计连续为true的次数,并将结果作为整数返回。使用时,只需要调用bools.ConsecutiveTrues()即可将布尔值列表合并为整数列表。
第二种方法是使用LINQ查询语句实现。首先将布尔值列表与其自身的移位后的列表进行压缩,然后按照连续相同的布尔值进行分组,并筛选出为true的分组,最后统计每个分组的数量作为整数返回。这种方法虽然使用了纯LINQ代码,但可读性较差,效率也相对较低。
文章最后提到了关于使用LINQ的讨论。有人认为LINQ虽然有其价值,但并不适合所有情况,过度使用LINQ会导致代码复杂且难以理解。然而,也有人认为在合理使用的前提下,LINQ可以简化问题的解决思路。最后,文章指出如果使用LINQ只是为了增加复杂性,那么说明设计存在问题。
总结起来,解决将布尔值列表合并为整数列表的方法有两种:使用迭代器实现的扩展方法和使用LINQ查询语句。虽然后者在某些情况下可能效率较低且可读性较差,但在合理使用的前提下仍然具有一定的价值。
问题的出现原因是:需要将一个bool类型的列表转换为int类型的列表,其中bool类型的True表示1,False表示0。
解决方法是使用LINQ的Aggregate方法,通过使用一个累加器和一个累加器函数来实现列表的转换。首先,设置一个空的int类型的列表作为累加器,然后遍历bool列表中的每个元素。根据元素的值,进行相应的操作:如果元素为True且累加器列表为空,则将1添加到累加器列表中;如果元素为True且累加器列表不为空,则将累加器列表中最后一个元素加1;如果累加器列表不为空且最后一个元素大于0,则在累加器列表中添加一个0。最后,对累加器进行一些额外的处理,如果累加器列表不为空且最后一个元素为0,则将最后一个元素移除。最终得到的累加器列表就是转换后的int类型的列表。
代码如下:
Listlst = new List () { true, true, true, false, true, true, true, true, false, false, true, true, true }; var bb = lst .Aggregate(new List (), (acc, element) => { if (element == true && acc.Count < 1) acc.Add(1); else if (element == true && acc.Count > 0) acc[acc.Count - 1] = 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}
以上就是将bool类型的列表转换为int类型的列表的方法。