web-dev-qa-db-ja.com

文字列配列の削減

Reduce関数を介してString配列の要素を結合しようとしています。少し試してみましたが、問題が正確にわからないのです。これは私がトリックを行うべきだと私が信じていることです。私は他の選択肢も試しましたが、膨大な量を考えると、いくつかの入力を待ちます:

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と組み合わせて文字列としても生成されるはずです。ここで型システムとどういう関係があるのか​​わかりません。何か案が?

14
Nicola Miotto

削減クロージャはおそらく次のようになります。

var jointGenres : String = genres.reduce("", combine: { $0 == "" ? $1 : $0 + "," + $1 })

これには"" の代わりに 0あなたが持っていたように、そして戻り値の始めに余分なコンマがないことを確認してください。

documentation でUとして表される戻り値の型が、文字列を追加しようとしているときに、元々0であったため、元のコードは機能しませんでした。あなたの場合、UとTの両方がIntではなくStringsを表すことを本当に望んでいます。

23
erdekhayser

最初の要素に特別な処理が必要なため、reduceはここでは簡単な解決策ではありません。この目的には、文字列の結合メソッドが適しています。

let strings = ["a", "b", "c"]
let joinedString = ",".join(strings)

配列が空でないことがわかっている場合は、reduceを使用して、条件を回避する別の解決策が考えられます。

let joinedStrings = strings[1..<strings.count].reduce(strings[0]) { $0 + "," + $1 }
14
Mihai Damian

ココアにはすでにこれを行う機能があります。 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
AlexT

Swift 4:

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

問題は、reduceに対する最初の引数です。これはアキュムレータであり、整数リテラルであり、ブロックの最初の実行時に$0として渡されるものです。これに文字列を追加するようにreduce関数に要求しています。

アキュムレータ引数として0の代わりに、空の文字列である""を渡す必要があります。

これは機能します:

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