2016-07-04 4 views
1

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

var indexes = [3,4,9,11] 
myArray.filter(...) 
+0

'filter' будет неэффективным, так как она будет выглядеть на каждое значение в' myArray'. Подумайте, что произойдет, если у 'myArray' было 100 тысяч предметов. Ваш метод итерации массива индексов будет циклически 4 раза, но фильтр будет циклически (внутренне) 100 тысяч раз. – vacawama

ответ

3

Если предположить, что

  • данных показателей в увеличении порядка и
  • все индексы действительны для массива (т.е. меньше, чем количество элементов),

, то простая операция карта будет работать:

let indexes = [2, 4, 7] 
let myArray = ["a", "b", "c", "d", "e", "f", "g", "h"] 

let filtered = indexes.map { myArray[$0] } 
print(filtered) //["c", "e", "h"] 

Примечание: В более ранних версиях Swift, был PermutationGenerator именно для этой цели:

let filtered = Array(PermutationGenerator(elements: myArray, indices: indexes)) 
print(filtered) //["c", "e", "h"] 

Однако это уже противопоказывается в Swift 2.2 и будет удален в Swift 3. Я еще не видел замену Swift 3.

+0

mhm это звучит круто. Требования 2 всегда удовлетворяются. Является ли это решение более эффективным, чем итерация? – aneuryzm

+0

@Patrick: Вы должны проверить это. Я уверен, что 'map()' итерирует внутри. - Возможными преимуществами по сравнению с явным циклом являются: Более короткий функциональный код, а результат - * постоянный *. –

0

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

let myArray = ["a", "b", "c", "d", "e"] 
var indexes = [1, 3] 
myArray.filter { (vowel) -> Bool in 
    if let index = myArray.indexOf(vowel) { 
     return indexes.contains(index) 
    } 
    return false 
} 
+0

Считаете ли вы, что это более эффективно, чем итерация? – aneuryzm

+0

noway: D Я не мог придумать какой-либо эффективный способ сделать это в фильтре –

+0

Я вижу, хорошо, тогда лучший способ - итерация, я думаю. – aneuryzm

0

Вы также можете использовать flatMap для получения отфильтрованного подмассив

let indexes = [2, 4, 7] 
let myArray = ["a", "b", "c", "d", "e", "f", "g", "h"] 

let subArray = indexes.flatMap { (index) -> String? in 
    return (0 <= index && index < myArray.count) ? myArray[index] : nil 
} 
Смежные вопросы