2016-01-14 1 views
3

Прежде всего, этот вопрос не о том, «что означает $ 0». В быстром документе я узнал, что $ 0 - как индекс.

Мой вопрос: «Как numbers.sort { $0 > $1 } может использоваться для реализации функции сортировки». Я искал этот синтаксис numbers.sort { $0 > $1 } на некоторых других сайтах, например this one. По-видимому, это не текущая версия. Поэтому я до сих пор не могу понять, в чем смысл этого.

print(numbers) //[20, 19, 1, 12] 
let sortedNumbers = numbers.sort { $0 > $1 } 
print(sortedNumbers) //[20, 19, 12, 1] 

Может кто-нибудь объяснить этот простой кусок кода выше для меня? Как этот простой код $0 > $1 реализует функцию сортировки, сортируя числа от большого до малого.

Я знаю, что некоторые об индексе, и это $ 0 выглядит как индекс, но он имеет только $ 0 и $ 1 два индекса. Итак, как его можно использовать в 4 числах? По моим знаниям на C++ раньше, я не могу понять принцип в этом.

Пожалуйста, сделайте свой ответ как конкретным, насколько это возможно. Спасибо!

----------------- Ниже редактируется дополнительная часть -------------------

I не знаю, сможет ли stackoverflow разрешить мне изменить мой вопрос, как это, но эта дополнительная часть слишком длинная, поэтому я не могу добавить ее в комментарий. @pbodsk @Paul Richter

Итак, синтаксис sort() в swift использует быструю сортировку для работы с функцией сортировки?

На самом деле, мой вопрос о «Принцип работы от sort{$0 > $1}». Я знаю, что вы имеете в виду выше, и я думаю, что это похоже на то, что говорит быстрый документ 2.1, но ваш ответ не то, что я действительно хочу знать. Извините, мое английское выражение не очень хорошо. Позвольте мне попробовать по-другому.

Когда я узнал C++ раньше, всегда есть какие-то документы, чтобы объяснить, что принцип работы функции во или как эта функция (как рода() здесь) работают в фоновом режиме. Sort() здесь нужно сравнить первый и второй обмен. В C++ это похоже на

if numbers[1] < numbers[2]{ //just consider this pseudocode 
    int k; 
    k = numbers[1]; 
    numbers[1] = numbers[2]; 
    numbers[2] = k; 
} 

Мы видим, что этот процесс очевиден. В быстром, это как

numbers.sort({(val1: Int, val2: Int) -> Bool in 
    return val1 > val2 
}) 

Где его сравнивают? И как это взаимообмена? Может ли return val1 > val2 автоматически сравнивать и менять эти два значения и возвращать их? Только этот синтаксис реализует эти все 3 процесса? Как? Это то, что я действительно хочу знать. Извините снова за мое бедное английское выражение.

+0

Вы смотрите рода стенография синтаксис .. . $ 0 фактически представляет вашу левую переменную, а $ 1 представляет вашу правую переменную. –

+1

Возможный дубликат [Что означает $ 0 в закрытии в Swift?] (Http://stackoverflow.com/questions/27491620/what-does-0-represent-in -closures-in-swift) – Cristik

+0

Это в каждом представлении к Swift. Посмотрите на закрытие, а затем на различные ярлыки для написания закрытий. – gnasher729

ответ

18

@the_UB и @moonvader оба правы, но я просто подумал, что я хотел бы расширить пример из @moonvader немного, чтобы показать вам, как мы в конечном итоге с $0 > $1

Если посмотреть на пример в «Быстрый язык программирования» около Closure Expressions вы можете видеть, что для сортировки массива вы вызываете метод sort, который затем может принимать функцию в качестве параметра.

Эта функция должна принимать два параметра и сравнивать их, а затем возвращать логическое значение.

Так что, если у нас есть этот массив:

let numbers = [4, 6, 8, 1, 3]

и этот метод

func sortBackwards(val1: Int, val2: Int) -> Bool { 
    print("val1: \(val1) - val2: \(val2)") 
    return val1 > val2 
} 

Мы можем сортировать элементы, как так:

numbers.sort(sortBackwards) //gives us [8, 6, 4, 3, 1]

sort методбудет использовать наш метод sortBackwards для каждого из элементов массива и сравнить их.

Вот выход print

val1: 6 - val2: 4 
val1: 8 - val2: 4 
val1: 8 - val2: 6 
val1: 1 - val2: 4 
val1: 3 - val2: 1 
val1: 3 - val2: 4 

ОК, давайте уменьшить это.

Вместо того, чтобы определить функцию, можно добавить, что непосредственно в качестве параметра методу sort следующим образом:

numbers.sort({(val1: Int, val2: Int) -> Bool in 
    return val1 > val2 
}) 

И мы до сих пор в конечном итоге с [8, 6, 4, 3, 1] (как повезло!)

ОК, следующее, что мы можем сделать, это то, что в «Быстрого языка программирования» (ссылка выше) называется «Вывод типа из контекста». Как мы называем этот метод на массиве Int, Свифт может выяснить, что наши val1 и val2 параметры должны быть Int с, нам не нужно рассказывать об этом. Таким образом, удалите типы. Это оставляет нам:

numbers.sort({val1, val2 in 
    return val1 > val2 
}) 

И все тот же результат.

ОК, попадая туда. Следующее, что мы можем сделать, - это то, что в книге называется «Неявные возвращения из закрытий с одним выражением»

Поскольку наше сравнение может быть выполнено в одной строке, нам не нужно использовать return. Итак:

numbers.sort({val1, val2 in val1 > val2}) 

Тем не менее дает нам [8, 6, 4, 3, 1]

Наконец мы добираемся к тому, что @moonvader используется гораздо гораздо меньше слов, чтобы объяснить :-) а именно «Стенография Довод Имена»

Как говорится в книге:

Swift автоматически предоставляет сокращенные имена аргументов встраивать затворы, которые могут быть использованы для обозначения значений аргументов замыкания имен $ 0, $ 1, $ 2 , и так далее.

Таким образом, в нашем примере, val1 можно заменить $0 и val2 можно заменить $1

Который дает нам:

numbers.sort({$0 > $1}) 

И все же мы получаем [8, 6, 4 , 3, 1]

Затем мы можем продолжить использование «Trailing Closure», что означает, что если последний параметр функции является закрытием, мы можем добавить этот параметр eter "вне" функции.

Таким образом, мы в конечном итоге с:

numbers.sort{$0 > $1} 

И исход по-прежнему [8, 6, 4, 3, 1]

Надежда, что помогает прояснить вещи.

1

Вот что нужно знать: Sort and Sorted.

Чтобы быть более конкретным, сортировка может быть двух типов: по возрастанию и по убыванию.

Q - Чтобы сделать сортировку, что нам нужно?

- Нам нужны две переменные для хранения двух переменной (я не знаю, если это правильное слово)

Следовательно, в этом случае мы имеем два переменных $0 и $1. Они оба являются сокращенными символами, представляющими левую и правую переменные. Оба помогут сортировать.

">" будет выполнять спуск.

"<" будет делать восходящий.

+1

"sorted" был в Swift 1 и устарел. Теперь мы используем «sort» и «sortInPlace». Это сообщение в блоге устарело. – Moritz

+0

Спасибо за обновление! –

1

From developer.apple.com

Сокращенного Аргумент Имена

Swift автоматически предоставляет сокращенные имена аргументов встраивать затворы, которые могут быть использованы для обозначения значений аргументов замыкания имен $ 0, $ 1, $ 2, и так далее.

Если вы используете эти имена сокращенных аргументов в своем выражении закрытия, вы можете опустить список аргументов закрытия из его определения, а число и тип имен сокращенных аргументов будут выведены из ожидаемого типа функции. В ключевом слове также может быть опущено, поскольку выражение укупорочного полностью состоят из его тела:

reversed = names.sort({ $0 > $1 }) 

Здесь $ 0 и $ 1 относятся к первым и вторым аргументам Струнных закупоривающим.

+0

Спасибо, но большая часть вашего ответа - это то, что говорит быстрый документ 2.1, который я читал много раз. –

0

Процесс сортировки списка состоит из многократного переупорядочения его элементов, пока ничего не изменится. Сейчас существует множество алгоритмов сортировки, но все они делают это по-разному. Итак, как элементы переупорядочиваются? Сравнивая два заданных элемента и определяя, что на первом месте, и заменяя их, если необходимо.

Мы можем разделить общие переназначения и подкачку часть из части сравнения и написать функцию сортировки, которая будет заботиться о всех повторяющихся вещах переупорядочения, и просто требуем звонящего указать как сравнить два элемента. Если список состоит из цифр, почти всегда бывает, что способ их сравнить - это просто принять их значение. Но предположим, что список состоит из вещей немного сложнее, например, автомобилей. Как вы сравниваете две машины? Ну, вы можете сравнить их, количественно сравнивая их максимальную скорость. Или их пробег газа. Или цена.

Но сравнение не обязательно должно быть числовым. Мы могли бы сравнить два автомобиля, фактически участвуя в гонке. Мы могли бы сравнить две машины, просто сказав, что если синий, а другой нет, синий сначала заказывается, и если ни один, ни оба они не являются синими, они заказываются, как они есть.

Мы можем придумать всевозможные способы сравнить две машины. И алгоритм сортировки мог затем отсортировать список автомобилей, не зная ничего о машинах, пока мы, вызывающий, просто рассказываем, как сравнивать автомобили - любые две машины. Нам просто нужно выразить это сравнение как выражение, возвращающее логическое значение, где, если это правда, первый автомобиль заказывается перед вторым, а если он ошибочен, первый автомобиль заказывается после второго.

Возвращаясь к номерам, это то, что sort { $0 > $1 } означает очень сжатый синтаксис Swift: «Сортировка, где, если первый элемент - второй, закажите первый перед вторым».

Вы спросили, как он может сортировать четыре числа только с двумя индексами. $ 0 и $ 1 не привязаны к четырем конкретным элементам в списке [20, 19, 1, 12], они привязаны к любым двум заданным номерам, которые необходимо сравнить, поскольку алгоритм сортировки требует повторного выполнения.

Необходимо отметить несколько вещей. Во-первых, оператор> должен быть определен для типов элементов, которые вы сортируете. В примере элементы являются числами, а> действительно определены. Во-вторых, функция sort указывает, что булевский истинный порядковый номер первого перед вторым, а не наоборот, поэтому функция сравнения следует этой спецификации. В-третьих, последнее оцениваемое выражение принимается за булево значение, которое нужно использовать. Предварительно допуская эти два предположения, функция сравнения должна быть написана так кратко.

Так что, если мы хотим, чтобы сортировать эти автомобили мчась их, мы могли бы написать так:

cars.sort { 
    winner_of_race_between($0, $1) == $0 
    // if the first car beats the second, it is sorted ahead 
} 

или монопольной синеву:

cars.sort { //not guaranteed to be valid Swift, just consider this pseudocode 
    if(($0.color != Color.blue) && ($1.color == Color.blue) { 
    $1 
    } else if (($0.color == Color.blue) && ($1.color != Color.blue)) { 
    $0 
    } else { //leave them in same order 
    $0 
    } 
} 
Смежные вопросы