Подтвердить что ты не робот

Есть что-то в Swift, как LINQ в С#

Я знаю, что Swift относительно новичок, но я хотел бы знать, есть ли у Swift что-то вроде LINQ в С#?

С LINQ я имею в виду все превосходные инструменты, такие как стандартные операторы запросов, анонимные типы, инициализатор объектов и т.д.

4b9b3361

Ответ 1

Swift включает в себя несколько функций, которые объединены в .net как LINQ, хотя, возможно, и не в полном объеме.

Анонимные типы довольно близки к кортежам с именованными значениями в Swift.

В С#:

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

Выход: Smith

В Swift:

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

Выход: Smith

Запросы LINQ, конечно, очень мощные/выразительные, но вы можете реплицировать большую часть того, что они делают, используя map, filter и reduce в Swift. С помощью lazy вы можете получить ту же функциональность, где вы создаете объект, который можно зацикливать заблаговременно, и оценивать его только тогда, когда происходит цикл:

В С#:

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

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

В 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 делают операции записи аналогичными существующим функциям LINQ довольно простыми. Например, из статьи LINQ wikipedia:

CountОператор 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]

Ответ 2

Я бы использовал CoreData или NSPredicate для некоторых функций LINQ. Я уверен, что это сетка со Свифт. Я использовал его только в Objective-C, но я видел статьи, которые реализуют его с помощью Swift.

http://nshipster.com/nspredicate/

Ответ 3

См. также:

https://github.com/slazyk/SINQ

Несмотря на то, что он немного устарел, поскольку Swift теперь включает в себя встроенную функцию lazy().