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

Ios 根据元素的出现情况获取数组的子集,ios,arrays,swift3,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} 我遵循这一点,但无法想出如何做上述事情 有什么方法可以做到这一点吗?您可以使用NSCountedSet来获取arr中所有元素的计数,然后您可以构建一个字典,其中键将是元素的出现次数,值将是具有出现次数键的元素数组。通过迭代Set(ar

我有这样一个数组:

var arr = [4,1,5,5,3]
我想根据数组中元素的出现情况从数组中提取子集

例如:

Elements with frequency 1 is {4,1,3}
Elements with frequency 2 is {5,5}
我遵循这一点,但无法想出如何做上述事情


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

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

对于打印,您只需要迭代字典中的键,并打印键及其对应的值。我只是对按键进行排序,使打印按发生次数的升序进行

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]!)}")
}
就是这样:

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
ext
S
tep类),并且使用了您提供的SO链接中的想法


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

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


操场测试:

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]

请注意,使用NSCountedSet不会保留数组order@Dávid Pásztor我收到错误“不能用类型为“(Int,default:[Any])(aka“(Int,default:Array)”)的索引为“[Int:[Int]]”类型的值下标。”@Rumin您确定使用的代码与我的完全相同吗?哪一行抛出错误?代码在操场上运行得很好。顺便说一句,您还必须确保导入了
Foundation
(如果您导入
UIKit
,这也会导入
Foundation
)才能使用
NSCountedSet
。是的,我在操场上运行的是相同的代码。。我还进口了基础。请检查您提供的代码是否与您正在运行的代码相同。@Rumin是的,这与我在操场上运行的代码完全相同。它还可以在IBMSwift沙盒上完美运行。您使用的是什么Swift版本?我的代码使用Swift 4。我得到了一个错误:“不能用类型为“(\u,默认值:Int)”的索引为“[\u:Int]”类型的值下标@Rumin您的Xcode版本是什么?您使用的是Swift 4吗?频率为N的元素如何?需要注意的是,此函数实际上并不能解决整个问题。您需要知道阵列中存在哪些频率才能有效地使用此功能。在不知道这一点的情况下,如果想要找到数组的所有子集,函数的性能就会变得非常糟糕。@DávidPásztor我想这就是要求的。目前的频率可以在
计数中找到,因此如果需要的话,很容易将这种逻辑转化为另一种形式。请您发表评论和/或奖励好吗?
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]