1

I need to get a total size of a 2d list. This is my implementation:

    fun totalSize(parts: List<List<String>>): Int {
        return parts.reduce { total, next -> total + next.size }
    }

I get type inference fail. Required Int, Got List. But next.size should return Int.

OMGPOP
  • 1,995
  • 8
  • 52
  • 95
  • I think the signature of reduce will force total to be the same as the inner type (e.g. List.reduce would have an Integer total). – charles-allen Aug 15 '17 at 05:49
  • @CodeConfident doesn't seem that way: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reduce.html reduce operation is `operation: (acc: S, T) -> S` T being the type in the list, S the output. – njzk2 Aug 15 '17 at 05:55
  • 2
    There's a type constraint on the line before that: `inline fun ` - i.e. T (input type) must be a subtype of S (the returned type). – charles-allen Aug 15 '17 at 05:57
  • 1
    good point. reduce wouldn't work here. fold would. – njzk2 Aug 15 '17 at 06:05
  • Wow... I always thought `reduce` and `fold` were synonyms! – charles-allen Aug 15 '17 at 08:29

2 Answers2

4

Better: map operation during sum (from @Ruckus T-Boom comment)

parts.sumBy { it.size }

Original: map the inner lists to their sizes first (guessing Kotlin syntax):

parts.map { l -> l.size }.reduce { total, i -> total + i }
charles-allen
  • 3,891
  • 2
  • 23
  • 35
2

In reduce, the first value for total is the first element of the list, which is also a list. So the inferred type for the return value of the reduce has to be List.

You can use fold instead:

return parts.fold(0, { total, next -> total + next.size })
njzk2
  • 38,969
  • 7
  • 69
  • 107
  • @OMGPOP - I think this answer is more idiomatic for your problem! Thanks njzk2 for educating me on the difference between reduce & fold. I even continued to read more detail here: https://stackoverflow.com/questions/25158780/difference-between-reduce-and-foldleft-fold-in-functional-programming-particula – charles-allen Aug 15 '17 at 09:07