Scala中的LINQ类似物?

时间:2010-09-24 08:33:18

标签: linq scala

对于Scala,是否存在任何与LINQ(.NET)相似的类比?

4 个答案:

答案 0 :(得分:55)

这取决于“LINQ”究竟是什么意思。 LINQ有很多东西。

最明显的答案是:只使用Scala的.NET端口。它为您提供对.NET中所有内容的完全本机访问,显然包括LINQ。

不幸的是,Scala的.NET端口在几年前被删除了。幸运的是,它在几个月前再次被提起,直接来自微软的官方资金也不少。您可以期待在2011/2012年的某个时间段内发布。

无论如何,什么是LINQ?

添加到.NET的一些功能,特别是用于 LINQ的C#和VB.NET 。它们在技术上不是LINQ的一部分,但它们是必要的先决条件:类型推断,匿名(结构)类型,lambda表达式,函数类型(Func<T...>Action<T...>)和表达式树。所有这些都已经在Scala中存在了很长时间,大多数都在那里永远存在。

也不是LINQ的直接部分,但在C#中,LINQ查询表达式可用于生成XML,以模拟VB.NET的XML文字。 Scala具有XML文字,如VB.NET。

更具体地说,LINQ是

  • 一组标准查询运算符的规范
  • 这些运算符的一组实现(即IQueryable,LINQ-to-XML,LINQ-to-SQL,LINQ-to-Objects)
  • LINQ查询理解的内置嵌入式语法
  • a monad

在Scala中,就像几乎任何其他函数式语言一样(实际上也几乎是任何其他面向对象的语言),查询运算符只是标准集合API的一部分。在.NET中,它们有一些奇怪的名称,而在Scala中,它们具有与其他语言相同的标准名称:SelectmapAggregate是{{1} }(或reduce),foldSelectManyflatMapWherefilterwithFilter为{{1} }或orderBysort,还有sortBysortWithzip等等。因此,它负责规范和LINQ-to-Objects实现。 Scala的XML库还实现了集合API,它负责LINQ-to-XML。

SQL API没有内置到Scala中,但是有第三方API实现了集合API。

Scala还有针对这些API的专用语法,但与Haskell不同,后者试图使它们看起来像命令式C块和C#,它们试图使它们看起来像SQL查询,Scala尝试使它们看起来像{{1} }循环。它们被称为 take comprehensions ,相当于C#的查询理解和Haskell的monad理解。 (它们也取代了C#的takeWhile和生成器(for))。

但如果确实想知道Scala中是否存在LINQ的类似物,那么首先必须具体说明“LINQ”究竟是什么意思。 (当然,如果你想知道它们是否“理智”,你也必须定义它。)

答案 1 :(得分:38)

Scala中提供了所有LINQ IEnumerable扩展。例如:

的LINQ:

var total = orders
       .Where(o => o.Customer == "myCustomer")
       .SelectMany(o => o.OrderItems)
       .Aggregate(0, (sum, current) => sum + current.Price * current.Count);

阶:

val total = orders
       .filter(o => o.customer == "myCustomer")
       .flatMap(o => o.orderItems)
       .foldLeft(0)((s, c) => s + c.price * c.count)

答案 2 :(得分:10)

光滑

是Scala的现代数据库查询和访问库。 (http://slick.typesafe.com/

@table("COFFEES") case class Coffee(
  @column("COF_NAME")  name:  String,
  @column("SUP_ID") supID: Int,
  @column("PRICE") price: Double
)
val coffees = Queryable[Coffee]


// for inserts use lifted embedding or SQL
val l = for {
  c <- coffees if c.supID == 101
  //                       ^ comparing Int to Int!
} yield (c.name, c.price)


backend.result( l, session )
 .foreach { case (n, p) => println(n + ": " + p) }

答案 3 :(得分:8)

Scala中有许多情况可以使用monadic构造作为一种查询语言。

例如,要查询XML(在这种情况下,从某些XHTML中的链接中提取URL):

def findURLs(xml: NodeSeq): Seq[URL] = 
  for {
    a <- xml \\ "a"
    href <- a attribute "href"
    url <- href.text
  } yield URL(url)

对于LINQ to SQL的模拟,最接近的可能是ScalaQuery。从文档中提取一个示例:

val q4c = for {
  u <- Users
  o <- Orders if o.userID is u.id
} yield u.first ~ o.orderID