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.
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.
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]
See also:
https://github.com/slazyk/SINQ
Even though it is a bit outdated since Swift now includes native lazy() functionality.
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.