2016-08-28 3 views
1

Есть ли простой способ удалить каждый n-й элемент из быстрого массива. Например, в приведенном ниже массиве:Удалите каждый n-й элемент из массива swift

thisArray = [2.0, 4.0, 3.0, 1.0, 4.5, 3.3, 1.2, 3.6, 10.3, 4.4, 2.0, 13.0] 

Если n = 3 и начать отсчет с первого элемента хотел бы вернуть:

returnThis = [2.0, 4.0, 1.0, 4.5, 1.2, 3.6, 4.4, 2.0] 

ответ

2
// swift 3: 
thisArray.enumerated().flatMap { index, element in index % 3 == 2 ? nil : element } 
  • Использование .enumerated() прикрепить индексы
  • Тогда используйте flatMap(), чтобы отфильтровать элементы по индексам 2, 5, 8, ..., вернув nil и разделив индекс на остальное на r eturning только element.

(Если вы застряли Swift 2 используйте .enumerate() вместо .enumerated().)

0

Одним из способов достижения этой цели является использование flatMap, который среди прочего, он удаляет Nils из массива, таким образом, мы будем просто вернуть nil для индексов мы хотим удалить:

let n = 3 
let arr = [2.0, 4.0, 3.0, 1.0, 4.5, 3.3, 1.2, 3.6, 10.3, 4.4, 2.0, 13.0] 
let filteredArr = arr.enumerate().flatMap {$0.index % n == n - 1 ? nil : $0.element } 

для быстрой 3:

let filteredArr = thisArray.enumerated().flatMap {$0.offset % n == n - 1 ? nil : $0.element } 

Вообще говоря, вы игнорируете N-1-й элемент массива.

Более функциональное решение может быть достигнуто с помощью махов:

let filteredArr = (n-1).stride(to: arr.count, by: n).flatMap { arr[($0-n+1)..<$0] } 

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

Или другой подход, с помощью reduce, что на самом деле в какой фильтр/карты/flatMap сводятся к:

let filteredArr = arr.enumerate().reduce([]) { $1.0 % n == n - 1 ? $0 : $0 + [$1.1] } 
// or, both produce the same results 
let filteredArr = arr.reduce((0,[])) { ($0.0 + 1, $0.0 % n == n - 1 ? $0.1 : $0.1 + [$1]) }.1 

И не в последнюю очередь, математический подход: взять множество индексов в массиве, вычтем индексы, которые мы не хотим, построен массив результатов из отсортированных привели индексов:

let filteredArr = Set(0..<arr.count).subtract((n-1).stride(to: arr.count, by: n)).sort(<).map { arr[$0] } 
2

Вы можете вычислить новый массив непосредственно из старого массива путем корректировки показателей. Для n=3 это выглядит следующим образом:

 
    0 1 2 3 4 5 6 7 8 ... old array index 
    | | // // 
    | | | | // 
    | | | |// 
    | |//// 
    0 1 2 3 4 5 6 ...  new array index 

Код:

let thisArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
let n = 3 

let newCount = thisArray.count - thisArray.count/n 
let newArray = (0..<newCount).map { thisArray[$0 + $0/(n - 1)] } 

print(newArray) // [1, 2, 4, 5, 7, 8, 10] 

После взятия n-1 элементов из старого массива вы должны пропустить один элемент. Это достигается добавлением $0/(n - 1) к индексу (новой) массива $0 при закрытии карты.

0

Поскольку функциональные стилевые решения уже размещены Я использую здесь старый моды путь подход

let nums = [2.0, 4.0, 3.0, 1.0, 4.5, 3.3, 1.2, 3.6, 10.3, 4.4, 2.0, 13.0] 

var filteredNums = [Double]() 
for elm in nums.enumerate() where elm.index % 3 != 2 { 
    filteredNums.append(elm.element) 
} 
Смежные вопросы