2014-10-27 6 views
0

Я читаю текстовый файл, содержащий строки ключа/значения в строках Swift. Одна из строк файла имеет пять разделенных пробелами значений в строке, которые я превратил в массив с помощью компонентовSeparatedByString.Скопируйте массив строк в массив из ints?

Фактические значения - это Ints, поэтому обычное решение должно было бы перебирать каждый из них и копировать его в соответствующий слот в массиве Int всей структуры. Но я пропустил магию Swift (или Foundation) здесь?

ответ

2

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

var array = ["2", "4", "6", "8"] 

let ints = array.map { $0.toInt()! } 

Обратите внимание, что я использую вынужден разворачивать при преобразовании в целом - так используйте его, если вы 100% уверен, что все элементы массива на самом деле являются целыми числами, в противном случае исключение во время выполнения будет сгенерирован

Безопаснее способ для сопоставления с опциональным целым числом, то фильтр, чтобы удалить ноль значений, а затем карту снова, чтобы заставить UnWrap УСТРОЙСТВА:

let ints = array.map { $0.toInt() }.filter { $0 != nil }.map { $0! } 

Обратите внимание, что это безопаснее версия может показаться медленнее, чем при использовании for цикла (и на самом деле это, потому что он проходит массив 3 раза - если компилятор не может его оптимизировать), но я предпочел бы его по циклу, потому что он более компактный и по-моему более читабельным. Разумеется, я бы, вероятно, не использовал для больших массивов.

Добавление: как это было предложено @MikeS, можно использовать reduce объединить последние 2 шага более безопасной версии:

let ints = array.map { $0.toInt() }.reduce([]) { $1 != nil ? $0 + [$1!] : $0 } 

Это выглядит как хорошая альтернатива для небольших массивов размера, потому что это уменьшает сложность от O (3n) до O (2n) - хотя я подозреваю, что без оптимизации компилятора это может быть медленнее, потому что на каждой итерации создается новый массив (если элемент не равен нулю) из-за $0 + [$1!].

Но это хорошо, чтобы знать, что есть много способов для достижения того же результата :)

+0

И * что * Вот почему я спросил. Очень полезно! –

+0

:) - прочитайте обновленный ответ для более безопасного способа сделать это – Antonio

+0

@Antonio вы можете удалить один из этих циклов, используя 'reduce' вместо' filter' и 'map', чтобы удалить' nil ':' let ints = array.map {$ 0.toInt()} .reduce ([]) {$ 1! = nil? $ 0 + [$ 1!]: $ 0} '. Вы также можете использовать 'сокращение' для выполнения начального сопоставления, но затем вы в основном возвращаетесь к циклу' for', и я не могу придумать способ сделать это как однострочный. –

Смежные вопросы