Ios Swift-按值对数组元素进行分组(2乘2、3乘3等)

Ios Swift-按值对数组元素进行分组(2乘2、3乘3等),ios,arrays,swift,sorting,swift3,Ios,Arrays,Swift,Sorting,Swift3,编辑:我不是要求函数计算发生次数。我要求一个函数来计算一次发生的次数2乘2,3乘3,10乘10,等等。。。这是我的问题 我有一系列的分数,比如说: [2,2,3,4,4,4,4,5,6,6,8,8,8,9,10,10] 我想用一个函数将这个数组转换成字典[Int:Int](),这样就可以: func groupArrayBy(array: Array<Int>, coef: Int) -> Array<Int, Int>{ // if coef = 2 -&

编辑:我不是要求函数计算发生次数。我要求一个函数来计算一次发生的次数2乘23乘310乘10,等等。。。这是我的问题

我有一系列的分数,比如说:

[2,2,3,4,4,4,4,5,6,6,8,8,8,9,10,10]
我想用一个函数将这个
数组
转换成
字典[Int:Int]()
,这样就可以:

func groupArrayBy(array: Array<Int>, coef: Int) -> Array<Int, Int>{
   // if coef = 2 -> 2 by 2, count occurence
   // Transform the array to:
   // [2: 3, 4: 5, 6: 2, 8: 4, 10: 2]
   // return Dictionary
}
func-groupArrayBy(数组:数组,coef:Int)->array{
//如果coef=2->2乘2,则计数发生次数
//将阵列转换为:
// [2: 3, 4: 5, 6: 2, 8: 4, 10: 2]
//返回字典
}
(如果coef=3,则为:
[2:7,5:3,8:6]
->3乘3)


我什么也没发现。有可能吗

您的问题太令人困惑了,以至于
coef
的意思是什么,或者我们可以期望输入数组被排序,您想要什么样的输出类型。Swift中没有
数组

假设输入数组已排序,并且需要
数组
,则可以编写如下内容:

func getRanges(_ arr: [Int], _ step: Int) -> [Range<Int>] {
    return stride(from: arr.first!, through: arr.last!, by: step)
        .map {$0..<$0+step}
}
func groupArrayBy(array: Array<Int>, coef: Int) -> [(Int, Int)] {
    let grpArr = getRanges(arr, coef).map {rng in
        (rng.lowerBound, arr.lazy.filter{rng.contains($0)}.count)
    }
    return grpArr
}

print(groupArrayBy(array: arr, coef: 2)) //->[(2, 3), (4, 5), (6, 2), (8, 4), (10, 2)]
print(groupArrayBy(array: arr, coef: 3)) //->[(2, 7), (5, 3), (8, 6)]
func getRanges(arr:[Int],uu步骤:Int)->[Range]{
返回步幅(从:arr.first!、到:arr.last!、按:步)
.map{$0..[(Int,Int)]{
设grpArr=getRanges(arr,coef).map{rng-in
(rng.lowerBound,arr.lazy.filter{rng.contains($0)}.count)
}
返回grpArr
}
打印(groupArrayBy(数组:arr,coef:2))/->[(2,3)、(4,5)、(6,2)、(8,4)、(10,2)]
打印(groupArrayBy(数组:arr,coef:3))/->[(2,7)、(5,3)、(8,6)]

我的代码效率不高,可能有人可以向您展示更高效的代码。

我仍然对系数有点困惑。但是,假设您希望将任何值
N
与下一个
N+系数
值分组

然后,我首先将原始数组重新映射到组值中:

let items = [2,2,3,4,4,4,4,5,6,6,8,8,8,9,10,10]

let uniqueItems = Set(items)
var itemCoefficientMapping: [Int: Int] = [:]

let coefficient = 3
for item in uniqueItems.sorted() {
    // look whether exists some lower value that is not itself mapped to another value
    let normalizedItem = (item - (coefficient - 1)...item).first {
        uniqueItems.contains($0) && itemCoefficientMapping[$0] == $0
    } ?? item
    itemCoefficientMapping[item] = normalizedItem
}

// count  by mapped value
let counts: [Int: Int] = items.reduce(into: [:]) { result, value in
    result[itemCoefficientMapping[value] ?? value, default: 0] += 1
}

print(counts)

这是我的版本,我根据数组的第一个值和
coef
变量过滤一个范围,根据结果我将已经计数的元素切掉,然后在循环中的较小数组上再次过滤。此解决方案要求输入数组按升序排序

func group(_ array: [Int], coef: Int) -> [Int: Int] {
    var result:[Int:Int] = [:]

    var start = array[0]
    var end = start + coef - 1
    var arr  = array

    while start <= array[array.count - 1] {
       let count = arr.filter({ $0 >= start && $0 <= end}).count

       result[start] = count
       start = end + 1
       end = start + coef - 1
       arr = Array(arr[count...])
    }
    return result
}
func组(uarray:[Int],coef:Int)->[Int:Int]{
变量结果:[Int:Int]=[:]
var start=array[0]
var end=start+coef-1
var arr=数组
而start=start&&$0[Int:Int]{
变量结果:[Int:Int]=[:]
if array.isEmpty{返回结果}
设end=array[0]+coef-1

让count=array.filter({$0>=array[0]&&&$0它可能有另一个更简单的代码,如下所示:

let aa : [Int] = [2,2,3,4,4,4,4,5,6,6,8,8,8,9,10,10]
let mini = aa.min()!
let coeff : Int = 3

let dict = Dictionary(grouping: aa) {
mini + (($0 - mini) / coeff) * coeff
   }.mapValues{$0.count}

print (dict)

我已经把它作为一个副本关闭了。对系数的要求只是计算所有内容的简单扩展(计算眼率,然后根据值>系数过滤结果).谢谢你的回答,但即使对你来说这看起来很简单,我也在为这一部分苦苦挣扎了好几个小时。我必须为此重新提出一个新问题吗?我试图调整功能,但没有success@Sulthan,我认为这个要求不够简单,不能被标记为重复。@Sulthan no这个代码似乎无法正常工作我不确定系数的实际含义。你能详细说明一下吗?太好了,这就是我要找的,谢谢。很抱歉混淆了
过滤器(谓词)。count
是一种反模式。它分配一个中间数组并复制所有传递的元素,只是为了计数它们,然后立即丢弃它们。使用
.count(where:predicate)
相反。@Alexander那么我想Swift是一种反模式,至少在我写这个答案时是这样,因为当时没有计数(where:)存在,我也不确定它是否存在。能给我指一些文档吗?哦,我想。(我的项目中有一个做同样事情的扩展).Nevermind,那么您可以求助于前面的最佳实践,即
array.lazy.filter(谓词).count
let aa : [Int] = [2,2,3,4,4,4,4,5,6,6,8,8,8,9,10,10]
let mini = aa.min()!
let coeff : Int = 3

let dict = Dictionary(grouping: aa) {
mini + (($0 - mini) / coeff) * coeff
   }.mapValues{$0.count}

print (dict)