Swift 2 Count数组匹配条件

时间:2015-10-05 19:21:36

标签: swift swift2

我基本上都在寻找以下c ++代码的快速等价物:

std::count_if(list.begin(), list.end(), [](int a){ return a % 2 == 0; }); // counts instances of even numbers in list

当然,我的问题实际上并没有搜索偶数数字;只是计算与标准匹配的实例的一般情况。

我还没有见过内置音乐,但很想听到我只是错过了它。

7 个答案:

答案 0 :(得分:23)

像这样:

 let a: [Int] = ...
 let count = a.filter({ $0 % 2 == 0 }).count

答案 1 :(得分:10)

替代Aderstedt的版本

let a = [ .... ]
let count = a.reduce(0){ 
    (count, element) in 
    return count + 1 - element % 2
}

我的直觉说我的方式会更快,因为它不需要创建第二个数组。但是,您需要对这两种方法进行分析以确定。

修改

关于MartinR关于函数泛化的评论,这里是

extension SequenceType
{
    func countMatchingCondition(condition: (Self.Generator.Element) -> Bool) -> Int
    {
        return self.reduce(0, combine: { (count, e) in count + (condition(e) ? 1 : 0) })
    }
}

let a = [1, 2, 3, 3, 4, 12].countMatchingCondition { $0 % 2 == 0 }
print("\(a)") // Prints 3

答案 2 :(得分:3)

执行此操作的最紧凑的reduce语句是:

let a = Array(1 ... 20)
let evencount = a.reduce(0) { $0 + ($1 % 2 == 0 ? 1 : 0) }

Reduce需要两个变量:从0(var $ 0)开始,然后对于Array a(var $ 1)中的每个元素,如果该值可以被2整除而没有余数,则将一个加到你的计数中。

这也很有效,因为与使用a.filter(){}不同,它不会创建额外的数组。计数。

答案 3 :(得分:2)

您也可以使用reduce()

执行此操作
let a = Array(1 ... 20)
let evenCount = a.reduce(0) { (accumulator, value) -> Int in
    guard value % 2 == 0 else { return accumulator }
    return accumulator + 1
}

使用map()filter函数几乎所有想做的事情实际上都可以使用reduce来完成,尽管它并不总是最具可读性。

答案 4 :(得分:1)

默认数组:

let array: [Int] = [10, 10, 2, 10, 1, 2, 3]

使用count(where:)

迅速5
let countOfTen = array.count(where: { $0 == 10 }) // 3

filter(_:)

扫描4或以下
let countOfTen = array.filter({ $0 == 10 }).count // 3

答案 5 :(得分:1)

迅速5或更高版本:

public extension Sequence {
    func occurrences(where predicate: (Element) throws -> Bool) rethrows -> Int {
        try reduce(0) { try predicate($1) ? $0 + 1 : $0 }
    }
}

public extension Sequence where Element: Equatable {
    func occurrences(of element: Element) -> Int {
        reduce(0) { element == $1 ? $0 + 1 : $0 }
    }
}

let multiplesOf2 = [1,2,3,4,4,5,4,5].occurrences{$0.isMultiple(of: 2)}  // 4
"abcdeabca".occurrences(of: "a")  // 3

extension BinaryInteger {
    var isOdd: Bool { !isMultiple(of: 2) }
    var isEven: Bool { isMultiple(of: 2) }
}

(-4).isOdd // false
(-3).isOdd // true
(-2).isOdd // false
(-1).isOdd // true
0.isOdd    // false
1.isOdd    // true
2.isOdd    // false
3.isOdd    // true
4.isOdd    // false

(-4).isEven // true
(-3).isEven // false
(-2).isEven // true
(-1).isEven // false
0.isEven    // true
1.isEven    // false
2.isEven    // true
3.isEven    // false
4.isEven    // true

let odds = [1,2,3,4,4,5,5,11].occurrences(where: \.isOdd) // 5
let evens = [1,2,3,4,4,5,5,11].occurrences(where: \.isEven) // 3

答案 6 :(得分:0)

您可以使用Collection.lazy来简化Aderstedt的答案,但要占用O(1)的空间。

let array = [1, 2, 3]
let count = array.lazy.filter({ $0 % 2 == 0 }).count