字符串数组缩减

20

我正在尝试使用reduce函数连接一个字符串数组中的元素。我已经尝试了一段时间,但是我无法确定问题出在哪里。这就是我认为可以解决问题的方法。我也尝试了其他替代方案,但由于数量巨大,所以我会等待一些输入:

var genres = ["towel", "42"]
var jointGenres : String = genres.reduce(0, combine: { $0 + "," + $1 })

错误:

..:14:44: 无法使用类型为“(IntegerLiteralConvertible,combine:(($T6,($T6,$T7)->($T6,$T7)-> $T5)->($T6,($T6,$T7)-> $T5)-> $T5,(($T6,$T7)->($T6,$T7)-> $T5,$T7)->(($T6,$T7)-> $T5,$T7)-> $T5)->(($T6,($T6,$T7)-> $T5)-> $T5,(($T6,$T7)-> $T5,$T7)-> $T5)-> $T5)” 的参数列表调用“+”

据我了解,$0应该被推断为一个字符串,$1与$0组合后也应该是一个字符串。我不知道这里的类型系统有什么问题。你有什么想法吗?

5个回答

30
你的reduce闭包应该长成这样:
var jointGenres : String = genres.reduce("", combine: { $0 == "" ? $1 : $0 + "," + $1 })

这里使用的是""而不是你之前使用的0,并确保返回值开头没有额外的逗号。

原始代码无法工作,因为在文档中表示为U的返回类型,在你的答案中最初是0,而你正在尝试将一个字符串添加到它上面。在你的情况下,你真正想要的是U和T都代表字符串而不是整数。


我忽略了第一个参数的含义,谢谢! - Nicola Miotto

24

在这里使用reduce并不是一个直截了当的解决方案,因为你需要对第一个元素进行特殊处理。使用String的join方法更加适合此目的:

let strings = ["a", "b", "c"]
let joinedString = ",".join(strings)
如果您知道数组不是空的,那么使用reduce还有另一个可能的解决方案,它也避免了条件语句:
let joinedStrings = strings[1..<strings.count].reduce(strings[0]) { $0 + "," + $1 }

3
在Swift 4中,必须执行joinedString = strings.joined(separator: ";")操作。 - Rool Paap

9

Cocoa已经有了一个实现此功能的函数。但需要进行类型转换才能使用NSArray。

var genres = ["towel", "42"]
var joinGenres = (genres as NSArray).componentsJoinedByString(",")

令我惊讶的是,这个函数也可以应用于除String以外的其他类型的数组:
let ints = [1,5,9,15,29]
let listOfInts = (ints as NSArray).componentsJoinedByString(",")

8

如果使用Swift 4:

var jointGenres:String = genres.joined(separator: ",")

2
问题出在你传给reduce的第一个参数。这是一个累加器,它是一个整数字面量,并且在块的第一次运行时作为$0传递。你要求reduce函数将一个字符串添加到此处。
相反,你应该将"",一个空字符串,作为累加器参数传递。
以下代码可以解决问题:
var genres = ["towel", "42"]
var jointGenres : String = genres.reduce("", combine: { $0 + "," + $1 })

2
这不完全正确,你需要使用@erdekhayser正在使用的三元表达式。 - iluvcapra

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