【问题标题】:Swift 4 - How to return a count of duplicate values from an array? [duplicate]Swift 4 - 如何从数组中返回重复值的计数? [复制]
【发布时间】:2017-10-29 04:52:56
【问题描述】:

我有一个包含多个值(双精度值)的数组,其中许多是重复值。我想返回或打印所有唯一值的列表,以及给定值在数组中出现的次数。我对 Swift 很陌生,我尝试了几种不同的方法,但我不确定实现这一目标的最佳方法。

类似这样的: [65.0, 65.0, 65.0, 55.5, 55.5, 30.25, 30.25, 27.5]

将打印(例如): “65.0 时 3 个,55.5 时 2 个,30.25 时 2 个,27.5 时 1 个。”

我真正关心的不是输出,而是实现这一点的方法。

谢谢!

【问题讨论】:

  • 如果您不介意使用 Foundation 框架,请查看 NSCountedSet 类。

标签: arrays swift


【解决方案1】:

正如@rmaddy 已经评论的那样,您可以使用Foundation NSCountedSet,如下所示:

import Foundation // or iOS UIKit or macOS Cocoa

let values = [65.0, 65.0, 65.0, 55.5, 55.5, 30.25, 30.25, 27.5]
let countedSet = NSCountedSet(array: values)
print(countedSet.count(for: 65.0))   // 3
for value in countedSet {
    print("Element:", value, "count:", countedSet.count(for: value))
}

Xcode 11 • Swift 5.1

您还可以扩展 NSCountedSet 以返回元组数组或字典:

extension NSCountedSet {
    var occurences: [(object: Any, count: Int)] { map { ($0, count(for: $0))} }
    var dictionary: [AnyHashable: Int] {
        reduce(into: [:]) {
            guard let key = $1 as? AnyHashable else { return }
            $0[key] = count(for: key)
        }
    }
}

let values = [65.0, 65.0, 65.0, 55.5, 55.5, 30.25, 30.25, 27.5]
let countedSet = NSCountedSet(array: values)
for (key, value) in countedSet.dictionary {
    print("Element:", key, "count:", value)
}

对于 Swift 原生解决方案,我们可以扩展 Sequence,将其元素限制为 Hashable

extension Sequence where Element: Hashable {
    var frequency: [Element: Int] { reduce(into: [:]) { $0[$1, default: 0] += 1 } }
}

let values = [65.0, 65.0, 65.0, 55.5, 55.5, 30.25, 30.25, 27.5]
let frequency = values.frequency
frequency[65] // 3
for (key, value) in frequency {
    print("Element:", key, "count:", value)
}

那些会打印出来的

Element: 27.5 count: 1
Element: 30.25 count: 2
Element: 55.5 count: 2
Element: 65 count: 3

【讨论】:

    【解决方案2】:

    您可以枚举数组并将值添加到字典中。

    var array: [CGFloat] =  [65.0, 65.0, 65.0, 55.5, 55.5, 30.25, 30.25, 27.5]
    var dictionary = [CGFloat: Int]()
    
    for item in array {
       dictionary[item] = dictionary[item] ?? 0 + 1
    }
    
    print(dictionary)
    

    或者你可以在数组上做foreach:

    array.forEach { (item) in
      dictionary[item] = dictionary[item] ?? 0 + 1
    }
    
    print(dictionary)
    

    或者正如@rmaddy所说:

    var set: NSCountedSet =  [65.0, 65.0, 65.0, 55.5, 55.5, 30.25, 30.25, 27.5]
    var dictionary = [Float: Int]()
    set.forEach { (item) in
      dictionary[item as! Float] = set.count(for: item)
    }
    
    print(dictionary)
    

    【讨论】:

    • if 可以替换为单个语句 dictionary[item] = dictionary[item] ?? 0 + 1 更好的是,只需使用 CountedSet :)
    • @DavidBerry,我已经更新了我的答案,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2019-05-22
    • 2017-03-06
    • 2016-11-04
    • 2015-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多