Search code examples
scalafunctional-programming

How could I correctly write this code in functional way without duplication


In the following function, I am passing an Option. Depending on whether the Option is Some or None, I need to call the a specific API but the rest of the code is the same for both Some and None. I don't know how to remove the code duplication though. How could I re-write the code in functional-programming style?

def getRowsByPartitionKeyId(id:I, pagingStateOption:Option[PagingState]):Tuple2[Option[List[M]],Option[PagingState]] = {
    pagingStateOption match {
      case Some(pagingState:PagingState) => {

        val resultSet = session.execute(whereClause
          .setFetchSize(1)
          .setPagingState(pagingState)) //THIS IS THE ONLY DIFFERENCE IN THE TWO CODE LEGS


        val it = resultSet.iterator();//resultSet is an iterator
        val newPagingState:PagingState = resultSet.getExecutionInfo.getPagingState


        if(it.hasNext){


          val resultSetAsList:List[Row] = asScalaIterator(it).toList
          val resultSetAsModelList = rowToModel(resultSetAsList.head)


          Tuple2(Some(List(resultSetAsModelList)),Some(pagingState))
        }
        else {
          Tuple2(None, None)
        }
      }
      case None =>{
        val resultSet = session.execute(whereClause
          .setFetchSize(1)) //get one row from ResultSet. Cassandra might return more or less though

        val it = resultSet.iterator();//resultSet is an iterator
        val pagingState:PagingState = resultSet.getExecutionInfo.getPagingState


        if(it.hasNext){


          val resultSetAsList:List[Row] = asScalaIterator(it).toList
          val resultSetAsModelList = rowToModel(resultSetAsList.head)


          Tuple2(Some(List(resultSetAsModelList)),Some(pagingState))
        }
        else {
          Tuple2(None, None)
        }    
      }
}

Solution

  • def getRowsByPartitionKeyId(
      id:I, 
      pagingStateOption:Option[PagingState]
    ): (Option[List[M]], Option[PagingState]) = {
    
      val resultSet = session.execute(pagingStateOption match {
        case Some(pagingState: PagingState) => 
          whereClause.setFetchSize(1).setPagingState(pagingState)
        case None =>
          whereClause.setFetchSize(1)
      })
    
      val it = resultSet.iterator();//resultSet is an iterator
      val newPagingState:PagingState = resultSet.getExecutionInfo.getPagingState
    
    
      if (it.hasNext) {
    
    
        val resultSetAsList:List[Row] = asScalaIterator(it).toList
        val resultSetAsModelList = rowToModel(resultSetAsList.head)
    
    
        Tuple2(Some(List(resultSetAsModelList)),Some(pagingState))
      } else {
        Tuple2(None, None)
      }
    }