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