问题
I know that Swift is relatively new yet, but I would like to know if Swift have anything like LINQ in C#?
With LINQ I mean all the excellent tools like Standard Query Operators, Anonymous types, Object Initializer, etc.
回答1:
Swift incorporates several of the features that are bundled together in .net as LINQ, though possibly not in quite an out-of-the-box sense.
Anonymous types are quite close to tuples with named values in Swift.
In C#:
var person = new { firstName = "John", lastName = "Smith" }; Console.WriteLine(person.lastName);
Output:
Smith
In Swift:
var person = (firstName: "John", lastName: "Smith") person.firstName = "Fred" print(person.lastName)
Output:
Smith
LINQ queries are of course very powerful/expressive, but you can replicate a large portion of what they do using map
, filter
and reduce
in Swift. With lazy
, you can get the same functionality where you create an object that can be looped over ahead of time, and only evaluate it when the looping actually happens:
In 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()); }
In Swift:
// 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 generics make writing operations similar to existing LINQ functionality quite straightforward. For example, from the LINQ wikipedia article:
Count The Count operator counts the number of elements in the given collection. An overload taking a predicate, counts the number of elements matching the predicate.
Could be written in Swift like this (2.0 protocol extension syntax):
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
You could also overload it to take a particular element to count if the element conforms to 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)
Structs by default have object-initializer-like syntax:
struct Person { let name: String; let age: Int; }
let person = Person(name: "Fred Bloggs", age: 37)
and via ArrayLiteralConvertible
, any collection type can have similar syntax to collection initializer syntax:
let list: MyListImplementation = [1,2,3,4]
回答2:
I'd personally use CoreData or NSPredicate for some LINQ like functionality. It meshes with Swift I'm sure. I've only used it in Objective-C, but I've seen articles people implementing it with Swift.
http://nshipster.com/nspredicate/
回答3:
See also:
https://github.com/slazyk/SINQ
Even though it is a bit outdated since Swift now includes native lazy() functionality.
来源:https://stackoverflow.com/questions/29655304/is-something-in-swift-like-linq-in-c-sharp