Collections Operations - Part 4 : Retrieving  parts of Collection

Collections Operations - Part 4 : Retrieving parts of Collection

In this article , lets discuss about Kotlin Collections operation - Retrieving parts of Collection using functions like slice , drop , take , windowed and chunked


Slice

  • returns the collection elements with the given indices in List<T>

we can slice with range values , range values with step count and we can do setOf() and listOf() also as follows

 val numbers = listOf(1,2,3,4,5,6,7,8,9)
    // slice int range
    println(numbers.slice(5..7))
    // output : [6, 7, 8]

    // slice step int range
    println(numbers.slice(0..6 step 2))
    //output : [1, 3, 5, 7]

    // slice setof
    println(numbers.slice(setOf(4,7,2,4)))
    // output : [5, 8, 3]

    // slice listOf
    println(numbers.slice(listOf(1,3,5,6,1)))
    //output: [2, 4, 6, 7, 2]

Take

take() - to get specified number of items from the beginning of input collection and returns List<T>

takeLast() - to get specified number/range of items from the end of input collection and returns List<T>

When we specify the number parameter larger than collection size , it returns the entire collection

takeWhile() - take() with predicate : it takes the items up to first item not matching predicate

takeLastWhile() - similar to takeLast() : first item of result is the next item to the last item not matching the predicate

   val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9)

    //take
    println(numbers.take(3))
    // output : [1, 2, 3]

    //takeLast
    println(numbers.takeLast(3))
    // output : [7, 8, 9]

    //take with parameter more than collection size
    println(numbers.take(11))
    // output : [1, 2, 3, 4, 5, 6, 7, 8, 9]

    // takeWhile
    println(
        numbers.takeWhile {
            it < 4
        }
    )
    // output : [1, 2, 3]

    // takeLastWhile
    println(
        numbers.takeLastWhile {
            it > 6
        }
    )
    //output : [6, 7, 8, 9]

Drop

drop() & dropLast()

  • drops the given number if items from the input collection and returns List<T>

  • drop() - drops from beginning of input collection

  • dropLast() - drops from end of input collection

dropWhile()

  • takes predicate

  • returns the elements from the first items not matching predicate to the end of input collection

dropLastWhile()

  • takes predicate

  • returns the elements from beginning of collection to last item not matching the predicate

         val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9)
    
         // drop
          println(numbers.drop(4))
          // output : [5, 6, 7, 8, 9]
    
          // dropLast
          println(numbers.dropLast(6))
          // output : [1, 2, 3]
    
          //dropWhile
          println(
              numbers.dropWhile {
                  it <= 7
              }
          )
          //output : [8, 9]
    
          // dropLastWhile
          println(
              numbers.dropLastWhile {
                  it >= 6
              }
          )
          //output : [1, 2, 3, 4, 5]
    

Chunked

  • breaks the collection into given size and returns list iof lists

  • first chunk start from first item in collection

  • last chunk may be of smaller size than given size

  • we can apply transformation to the chunked part right away

  • transformation lambda argument is chunk of collection and these chunked parts are scoped with lambda so we have to consume this with in lambda

          val numbers = (0..10).toList()
    
          // chunked
          println(numbers.chunked(3))
          //output :[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]
    
          // chunked with transformation
          val list = numbers.chunked(3) {
              it.average()
          }
          println(list)
          //output : [1.0, 4.0, 7.0, 9.5]
    

Windowed

  • retrieves all possible range of collection values/elements of given input size (window size)

  • returns list of items of the given size in a single list

Lets call each individual list in returned list as windows

step() - defines distance between first item of two adjacent windows and default step value is 1

partialWindows - include window of smaller size of last items at input collection end

Eg: if input collection is [0,1,2,3,4]and window size is 3 then the result is [0,1,2] , [1,2,3], [2,3,4],[3,4]

zipWithNext()

  • used to build two element windows

  • creates pair of adjacent items from input collection

  • it creates a Pair for each element except the last one like [1,2],[2,3],[3,4] and not [1,2], [3,4]

    we can apply transformation to the windowed() and zipWithNext()

  •       val numbers = (0..10).toList()
    
          // windowed
          println(numbers.windowed(3))
          // output : [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], 
          //[4, 5, 6], [5, 6, 7], [6, 7, 8], [7, 8, 9], [8, 9, 10]]
    
          // windowed with stop and partialWindows
          println(numbers.windowed(3, step = 3, partialWindows = true))
          // output : [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]
          println(numbers.windowed(3, step = 3, partialWindows = false))
          // output : [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
    
          // zipWithNext
          println(numbers.zipWithNext())
          // output : [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10)]
    
          // zipWithNext with transformation
          println(numbers.zipWithNext() { i1, i2 ->
              i1 + i2
          })
          // output : [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
    

Please leave your comments to improve.

Happy and Enjoy coding