scala
  • for-loop
  • 2013-04-23 38 views 0 likes 
    0

    我得到這個代碼https://github.com/Netflix/astyanax/wiki/Cql-and-cql3Netflix的Astyanax在斯卡拉

    我是新來的Scala和我的問題是轉換for循環的一個階。

    你能幫忙嗎?

    result = keyspace 
         .prepareQuery(CQL3_CF) 
         .withCql("SELECT * FROM employees WHERE empId='111';") 
         .execute(); 
    
    for (Row<Integer, String> row : result.getResult().getRows()) { 
        LOG.info("CQL Key: " + row.getKey()); 
    
        ColumnList<String> columns = row.getColumns(); 
    
        LOG.info(" empid  : " + columns.getIntegerValue("empid",  null)); 
        LOG.info(" deptid  : " + columns.getIntegerValue("deptid",  null)); 
        LOG.info(" first_name : " + columns.getStringValue ("first_name", null)); 
        LOG.info(" last_name : " + columns.getStringValue ("last_name", null)); 
    } 
    

    非常感謝

    這個代碼轉換成基於階循環結構將如下

    回答

    3

    方式一:

    import scala.collection.JavaConversions._ 
    
        val result = keyspace 
        .prepareQuery(CQL3_CF) 
        .withCql("SELECT * FROM employees WHERE empId='111';") 
        .execute(); 
    
        result.getResult().getRows() foreach { row => 
        LOG.info("CQL Key: " + row.getKey()) 
    
        val columns = row.getColumns() 
    
        LOG.info(" empid  : " + columns.getIntegerValue("empid",  null)) 
        LOG.info(" deptid  : " + columns.getIntegerValue("deptid",  null)) 
        LOG.info(" first_name : " + columns.getStringValue ("first_name", null)) 
        LOG.info(" last_name : " + columns.getStringValue ("last_name", null))  
        } 
    

    通過導入在JavaConversions._,我們獲得了一個隱式訪問轉換將Java Iterable(Rows對象所在的位置)轉換爲scala.collection.Iterable,從而允許您使用循環構造foreach

    現在,這段代碼在語法上是合理的,但它並不是很好的Scala代碼。它的功能不是很好,因爲循環本身不會返回任何東西。它也有一些凌亂的邏輯處理空值,可能應該使用Options來代替。該解決方案的,功能更強大例如使用map的結果數據到一個簡單的例子類映射看起來是這樣的:

    import scala.collection.JavaConversions._ 
    
    val result = keyspace 
        .prepareQuery(CQL3_CF) 
        .withCql("SELECT * FROM employees WHERE empId='111';") 
        .execute(); 
    
    case class Employee(id:Option[Int], depId:Option[Int], 
        firstName:Option[String], lastName:Option[String]) 
    
    def optFor[T](cl:ColumnList[String], func:(ColumnList[String] => T)):Option[T] = { 
        func(cl) match{ 
        case null => None 
        case nonnull => Some(nonnull) 
        } 
    } 
    
    val employees = result.getResult().getRows() map { row => 
        LOG.info("CQL Key: " + row.getKey()) 
        val cl = row.getColumns() 
        val employee = Employee(optFor(cl, _.getIntegerValue("empid", null)), 
        optFor(cl, _.getIntegerValue("deptid", null)), 
        optFor(cl, _.getStringValue("first_name", null)), 
        optFor(cl, _.getStringValue("last_name", null))) 
    
        LOG.info(employee) 
        employee 
    } 
    

    有可能來處理空到Option轉換更優雅的方式(通過implicits也許) ,但這也適用。在完成map操作後,您將有一個scala.collection.IterableEmployee實例,然後您可以返回到UI進行顯示。

    +3

    你可以用'Option(func(cl))'替換'optFor'的主體' – jqno 2013-04-23 12:59:08

    相關問題