【问题标题】:Is something in Swift like LINQ in C#Swift 中的东西就像 C# 中的 LINQ
【发布时间】:2015-04-15 16:06:22
【问题描述】:

我知道 Swift 还比较新,但我想知道 Swift 在 C# 中是否有类似 LINQ 的东西?

对于 LINQ,我指的是所有出色的工具,例如 标准查询运算符、Anonymous types、Object Initializer 等。

【问题讨论】:

标签: ios linq swift dsl


【解决方案1】:

Swift 将 .net 中作为 LINQ 捆绑在一起的几个功能结合在一起,尽管可能不是开箱即用的意义。

匿名类型非常接近 Swift 中具有命名值的元组。

在 C# 中:

   var person = new { firstName = "John", lastName = "Smith" };
   Console.WriteLine(person.lastName);

输出:Smith

在斯威夫特中:

var person = (firstName: "John", lastName: "Smith")
person.firstName = "Fred"
print(person.lastName)

输出:Smith

LINQ 查询当然非常强大/富有表现力,但您可以在 Swift 中使用 map、filter 和 reduce 复制它们所做的大部分工作。使用lazy,您可以获得相同的功能,即创建一个可以提前循环的对象,并且仅在循环实际发生时对其进行评估:

在 C# 中:

var results =
 SomeCollection
    .Where(c => c.SomeProperty < 10)
    .Select(c => new {c.SomeProperty, c.OtherProperty});

foreach (var result in results)
{
    Console.WriteLine(result.ToString());
}

在斯威夫特中:

// just so you can try this out in a playground...
let someCollection = [(someProperty: 8, otherProperty: "hello", thirdProperty: "foo")]

let results =
  someCollection.lazy
    .filter { c in c.someProperty < 10 }
    // or instead of "c in", you can use $0:
    .map { ($0.someProperty, $0.otherProperty) }

for result in results {
    print(result)
}

Swift 泛型使类似于现有 LINQ 功能的编写操作非常简单。比如来自LINQ wikipedia article:

计数 Count 运算符计算给定集合中元素的数量。采用谓词的重载,计算与谓词匹配的元素数。

可以像这样用 Swift 编写(2.0 协议扩展语法):

extension SequenceType {
    // overload for count that takes a predicate
    func count(match: Generator.Element -> Bool) -> Int {
        return reduce(0) { n, elem in match(elem) ? n + 1 : n }
    }
}

// example usage
let isEven = { $0 % 2 == 0 }

[1,1,2,4].count(isEven)  // returns 2

如果元素符合Equatable,您也可以重载它以对特定元素进行计数:

extension SequenceType where Generator.Element: Equatable {
    // overload for count that takes a predicate
    func count(element: Generator.Element) -> Int {
        return count { $0 == element }
    }
}

[1,1,2,4].count(1)

结构默认具有类似对象初始化器的语法:

struct Person { let name: String; let age: Int; }

let person = Person(name: "Fred Bloggs", age: 37)

通过ArrayLiteralConvertible,任何集合类型都可以具有与集合初始化器语法相似的语法:

let list: MyListImplementation = [1,2,3,4]

【讨论】:

  • 同意。这是最佳答案@AirspeedVelocity
  • 多么棒的答案,这正是我希望的答案。
  • 很好的答案,但没有解决限制。具体来说,linq 最有价值的资产是实现您自己的查询提供程序的能力,这在 swift 中是不可能的(至少不容易),因为第一类不支持代码的运行时解释。
  • 这一切都很好,但是到目前为止,Linq 最有价值的特性是能够在 DB 端执行。第 3 方开发人员开发了与最知名数据库的集成,因此 var a = entity.Where(x=> x.Age > 21) 被转换为 Sql 查询并远程执行。没有这个,Linq 的用处就会很低。
【解决方案2】:

我个人会使用 CoreData 或 NSPredicate 来实现一些类似 LINQ 的功能。我敢肯定,它与 Swift 相得益彰。我只在 Objective-C 中使用过它,但我看到有人用 Swift 实现它的文章。

http://nshipster.com/nspredicate/

【讨论】:

  • 是的,我知道NSPredicate,但是创建匿名类型等有更好的方法吗?
【解决方案3】:

另见:

https://github.com/slazyk/SINQ

尽管它有点过时了,因为 Swift 现在包含本机lazy() 功能。

【讨论】:

    猜你喜欢
    • 2012-03-29
    • 1970-01-01
    • 2014-11-06
    • 2011-08-13
    • 1970-01-01
    • 2010-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多