鉴于以下设想的例子:
public bool NumberOfEvensEqualsNumberOfOdds(IEnumerable<int> numbers) {
var numberOfEvens = numbers.Count(x => x % 2 == 0);
var numberOfOdds = numbers.Count(x => x % 2 != 0);
return numberOfEvens == numberOfOdds;
}
这有效,但需要多次枚举该集合。
是否可以重写它以使用枚举集合的单个linq表达式。
注意:我正在尝试解决将计数与两个过滤器进行比较的一般情况,因此请尝试忽略样本与奇数和偶数相关的事实。
我添加了一个示例.NET Fiddle
答案 0 :(得分:2)
您可以使用all_sights = params[:sights].split(',')
:
GroupBy
答案 1 :(得分:2)
乍一看有点神秘,但只能在集合中迭代一次。
Func<int, bool> isEven = n => n % 2 == 0;
Func<int, bool> isFive = n => n == 5;
int diff = numbers.Aggregate(0, (sum, next) => isEven(next) ? sum + 1 : isFive(next) ? sum - 1 : sum);
对于集合中的每个项目,它会检查这两个条件。如果第一个条件适用,它会向聚合变量添加一个;如果第二个适用,它会减去一个。最终结果是满足第一个标准的项目数与满足第二个标准的项目数之间的差异。
答案 2 :(得分:2)
如果你有两个不相交的过滤器(也就是说,一个项目不能同时满足这两个过滤器),那么BJ Myer的答案可能就像你能得到的那样简单有效。
如果你有两个不一定不相交的过滤器,那么你可以使用以下微小的变化,它总是评估每个项目的两个过滤器:
public static bool NumberOfEvensEqualsNumberOfOdds(IEnumerable<int> numbers)
{
// Compute
// numbers.Count(x => x % 2 == 0) - numbers.Count(x => x % 2 != 0)
// or equivalently,
// numbers.Sum(x => x % 2 == 0 ? 1 : 0) - numbers.Sum(x => x % 2 != 0 ? 1 : 0)
int sum = numbers.Sum(x =>
(x % 2 == 0 ? 1 : 0) -
(x % 2 != 0 ? 1 : 0));
return sum == 0;
}
如果你有任意数量的不一定不相交的过滤器,那么你可以使用以下通用方法:
public static bool HasEqualSizeSubsets<T>(
IEnumerable<T> items, params Func<T, bool>[] filters)
{
var indexedFilters = filters
.Select((filter, index) => new { Filter = filter, Index = index })
.ToArray(); // to avoid repeated object allocations later
IEnumerable<int> subsetSizes = items
.SelectMany(item => indexedFilters
.Where(indexedFilter => indexedFilter.Filter(item))
.Select(indexedFilter => indexedFilter.Index))
.GroupBy(index => index)
.Select(grouping => grouping.Count());
return subsetSizes.Distinct().Count() == 1;
}
HasEqualSizeSubsets看起来很复杂,但基本思路很简单:
filters
数组参数中传递的每个过滤器的数组索引。item
中的每个items
,我们得到item
满足的每个过滤器的索引。 (例如,如果item
仅满足第一个过滤器,则输出“0”。如果item
满足前两个过滤器,则输出“0”和“1”。)结果SelectMany调用是一系列过滤器索引。HasEqualSizeSubsets可以像这样使用:
public static bool NumberOfEvensEqualsNumberOfOdds(IEnumerable<int> numbers)
{
return HasEqualSizeSubsets(numbers, x => x % 2 == 0, x => x % 2 != 0);
}
答案 3 :(得分:1)
您使用.Aggregate
代码执行此操作:
public bool NumberOfEvensEqualsNumberOfOdds(IEnumerable<int> numbers)
{
var result =
numbers
.Aggregate(
new { evens = 0, odds = 0 },
(a, x) =>
{
a = x % 2 == 0
? new { evens = a.evens + 1, a.odds }
: a;
a = x % 2 != 0
? new { a.evens, odds = a.odds + 1 }
: a;
return a;
});
return result.evens == result.odds;
}
可以更新逻辑以计算来自源编号的不同投影的数量。
答案 4 :(得分:0)
如果您想检查两种不同的条件并仅循环一次。 你可以使用foreach循环并在
中拥有自己的逻辑Sub split_and_create()
Dim rw As Long, lr As Long, lc As Long, v As Long, vSTATs As Variant, vREGNs As Variant
With ActiveSheet
lr = .Cells(Rows.Count, 1).End(xlUp).Row
lc = .Cells(1, Columns.Count).End(xlToLeft).Column
.Cells(1, 2).CurrentRegion.Rows(1).Copy _
Destination:=.Cells(lr + 2, 1)
For rw = 2 To lr
vSTATs = Application.Index(.Cells(rw, 1).Resize(1, lc).Value, 1, 0)
vREGNs = Split(vSTATs(4), " - ")
For v = LBound(vREGNs) To UBound(vREGNs)
vSTATs(4) = vREGNs(v)
.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Resize(1, lc) = vSTATs
Next v
Next rw
End With
End Sub