如何将匹配的数组项分组到另一个数组中?

5
例如,假设我有一个如下所示的数组:
var someArray = ["1", "1", "2"]
我需要将其分成两个数组,看起来像这样:
["1","1"]
["2"]
我该如何处理?
任何帮助都将不胜感激!
4个回答

7

使用字典初始化器init(grouping:by:)

然后,通过访问values属性来获取数组。

示例:

let dic = Dictionary(grouping: someArray) { $0 }
let values = Array(dic.values)
print(values)

结果:

[["2"], ["1", "1"]]

这是最好的方法。他使用 O(N) 的运行时复杂度来匹配对象,而 @Bruno 的实现则使用了 O(N*N)。 - Robert D. Mogos
我的初始反对是因为它只是一个链接帖子。现在这绝对是我最喜欢的方法 :D - Fogmeister
在第一行,我遇到了一个错误:“无法推断出通用参数'key'”。 - farhan
let someArray: [String] = ["1","3","4","1"] - farhan
它可在Xcode 9中获取,您需要升级它。无论如何,这是为了开发iOS 11和iPhone X所必需的。 - kirander
显示剩余3条评论

3

以下是一些事实(点赞和回答应该发给 @kirander)

@kirander 的方法使用 Dictionary 将对象映射到 O(N) runtimeO(N) memory 中。

其他解决方案大多运行在 O(N*N) runtimeO(N) memory 中。因此,对一个随机的包含1000个项目的数组进行分组将需要:@kirander 的解决方案需要0.07秒,而其他解决方案需要34秒

func benchmark(_ title:String, code: ()->()) {
  let startTime = CFAbsoluteTimeGetCurrent()
  code()
  let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
  print("Time elapsed for \(title): \(timeElapsed) s.")
}

var array:[String] = []
for _ in 0...1000 {
  array.append("\(Int(arc4random_uniform(10)))")
}

// @kirander solution 0.07s
benchmark("Dictionary", code: {

  let dic = Dictionary(grouping: array, by: { $0 })
  let values = Array(dic.values)
})


// @Bruno solution ~34s
benchmark("Array", code: {
  var resultingArrays = [[String]]()
  for value in array {
    let ar = array.filter({ $0 == value })
    if !resultingArrays.contains(where: {$0 == ar}) {
      resultingArrays.append(ar)
    }
  }
})

很有趣看到这些解决方案如何扩展。谢谢你! - Bruno
我在尝试使用@kirander的解决方案时遇到了编译时错误“无法推断泛型参数'key'”。 - farhan

1
你可以尝试像这样做:

您可以尝试像这样做:

var someArray = ["1", "1", "2"]

var resultingArrays = [[String]]()

for value in someArray {
    let array = someArray.filter({ $0 == value })
    if !resultingArrays.contains(where: {$0 == array}) {
        resultingArrays.append(array)
    }
}

@kirander的评论已被编辑。现在我同意他的答案更有效和更好。 - Bruno
@RobertD.Mogos,这是我的观点,你可能有不同的看法。因为当我评论这个答案时,没有人给出适当的答案。所以在我看来,这是最好的答案。 - Ashok Londhe

-3
你可以试试这个:
let arrM = ["1","3","4","6","1","1","3"]
let arrSrtd = Array(Set(arrM))
 for ele in arrSrtd{
   let a = arrM.filter( {$0 == ele})
    print(a)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接