scala
  • for-loop
  • 2013-04-23 70 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

    相关问题