根据元素的出现获取数组的子集

时间:2018-01-17 00:10:22

标签: ios arrays swift3

我有一个像:

这样的数组
var arr = [4,1,5,5,3]

我想根据数组中元素的出现从数组中获取子集。

例如:

Elements with frequency 1 is {4,1,3}
Elements with frequency 2 is {5,5}

我跟着这个StackOverflow question,但无法弄清楚如何做上述事情。

我有什么方法可以做到这一点吗?

3 个答案:

答案 0 :(得分:1)

您可以使用NSCountedSet获取arr中所有元素的计数,然后您可以构建Dictionary,其中键将是元素的出现次数和值将是具有键出现次数的元素的数组。通过迭代Set(arr)而不是简单地arr来构建字典,您可以确保重复元素只添加到字典一次(例如,对于您的原始示例,5不会' t加上两次,频率为2)。

对于打印,您只需要遍历Dictionary的键并打印键及其对应的值。我只是按键排序,使打印按出现次数的升序排列。

let arr = [4,1,5,5,3,2,3,6,2,7,8,2,7,2,8,8,8,7]
let counts = NSCountedSet(array: arr)
var countDict = [Int:[Int]]()
for element in Set(arr) {
    countDict[counts.count(for: element), default: []].append(element)
}
countDict

for freq in countDict.keys.sorted() {
    print("Elements with frequency \(freq) are {\(countDict[freq]!)}")
}

输出:

Elements with frequency 1 are {[4, 6, 1]}
Elements with frequency 2 are {[5, 3]}
Elements with frequency 3 are {[7]}
Elements with frequency 4 are {[2, 8]}

Swift 3版本:

let arr = [4,1,5,5,3,2,3,6,2,7,8,2,7,2,8,8,8,7]
let counts = NSCountedSet(array: arr)
var countDict = [Int:[Int]]()
for element in Set(arr) {
    if countDict[counts.count(for: element)] != nil {
        countDict[counts.count(for: element)]!.append(element)  
    } else {
        countDict[counts.count(for: element)] = [element]
    }
}

for freq in countDict.keys.sorted() {
    print("Elements with frequency \(freq) are {\(countDict[freq]!)}")
}

答案 1 :(得分:1)

您只需要获取元素的出现次数并过滤仅出现一次或多次的元素,如answer所示:

extension Array where Element: Hashable {
    // Swift 4 or later
    var occurrences: [Element: Int] {
        return reduce(into: [:]) { $0[$1, default: 0] += 1 }
    }
    // // for Swift 3 or earlier
    // var occurrences: [Element: Int] {
    //     var result: [Element: Int] = [:]
    //     forEach{ result[$0] = (result[$0] ?? 0) + 1}
    //     return result
    // }
    func frequencies(where isIncluded: (Int) -> Bool) -> Array {
        return filter{ isIncluded(occurrences[$0] ?? 0) }
    }
}

游乐场测试:

let arr = [5, 4, 1, 5, 5, 3, 5, 3]

let frequency1 = arr.frequencies {$0 == 1}       // [4, 1]
let frequency2 = arr.frequencies {$0 == 2}       // [3, 3]
let frequency3orMore = arr.frequencies {$0 >= 3} // [5, 5, 5, 5]

答案 2 :(得分:0)

就是这样:

func getSubset(of array: [Int], withFrequency frequency: Int) -> [Int]
{
    var counts: [Int: Int] = [:]

    for item in array
    {
        counts[item] = (counts[item] ?? 0) + 1
    }

    let filtered  = counts.filter{ $0.value == frequency}

    return Array(filtered.keys)
}

这是纯粹的Swift(不使用好的N分机S tep类),并使用您提供的SO链接中的提示。

counts字典包含数组中每个int值(键)的频率(值):[int-value : frequency]