Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String array reduce

Tags:

swift

reduce

I am trying to join the elements of a String array via the reduce function. A tried for a bit now, but I can't get what the problem exactly is. This is what I believe should do the trick. I have tried other alternatives too, but given the huge amount I will wait for some input:

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

Error:

..:14:44: Cannot invoke '+' with an argument list of type '(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)'

From my understanding, $0 should be inferred as a String and $1, by combination with $0, should result as a String too. I don't know what's the deal with the type system here. Any idea?

like image 997
Nicola Miotto Avatar asked Sep 20 '14 17:09

Nicola Miotto


People also ask

Can you use reduce on a string JavaScript?

We use reduce() when we need to analyze all of the elements in an array and return just a single value, it can transform the data from the array into a number, string, or an object. The reducer function is always taking from the two elements (the accumulator and the current value) reducing them into one value.

Does reduce method work with strings?

An interesting aspect of the reduce method in JavaScript is that you can reduce over functions as well as numbers and strings.

What array reduce () does?

reduce() returns the value that is returned from the callback function on the final iteration of the array. reduce() is a central concept in functional programming, where it's not possible to mutate any value, so in order to accumulate all values in an array, one must return a new accumulator value on every iteration.

How do you reduce an array of arrays?

The reduce() method executes the function for each value of the array (non-empty array) from left to right. The reduce() method has the following syntax: let arr = [];arr. reduce(callback(acc, curVal, index, src), initVal);


2 Answers

Your reduce closure should probably look like this:

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

This has the "" instead of 0 like you had, and makes sure that there is no extra comma in the beginning of the return value.

The original code did not work because the return type that is represented as U in documentation was originally 0 in your answer, while you are trying to add a String to it. In your case, you really want both U and T to represent Strings instead of Ints.

like image 114
erdekhayser Avatar answered Oct 14 '22 10:10

erdekhayser


reduce is not a straightforward solution here since you need special handling for the first element. String's join method is better for this purpose:

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

If you know the array is not empty there is another possible solution with reduce that also avoids conditionals:

let joinedStrings = strings[1..<strings.count].reduce(strings[0]) { $0 + "," + $1 }
like image 22
Mihai Damian Avatar answered Oct 14 '22 08:10

Mihai Damian