2017-02-27 68 views
1

我有一個年齡數組。我想根據年齡值將數組拆分爲4個子數組。通過變量值將數組拆分爲子陣列

A - > 0 ... 25

乙 - > 26 ... 50

Ç - > 51 ... 75

d - > 76 +

我沒有問題迭代通過數組並通過年齡值附加到不同的數組。

  let subArrays: [[Int]] = [[], [], [], []] 
      for age in ages { 
       switch age { 
       case 0...25: 
        subArrays[0].append(age) 
       case 26...50: 
        subArrays[1].append(age) 
       case 51...75: 
        subArrays[2].append(age) 
       default: 
        subArrays[3].append(age) 
       } 
      } 

我的問題是: 有沒有做到這一點使用mapsplit或任何其他功能的更清潔的方式。

感謝

+1

它是安全的假設你的意思是'd - > 76 +',而不是'd - > 85 +'? – rmaddy

回答

3

這不使用map或任何幻想,但你可以很容易地消除switch

var subArrays: [[Int]] = [[], [], [], []] 
for age in ages { 
    subArrays[min((age - 1)/25, 3)].append(age) 
} 

採用min保證了76的所有值和更大的進入最後的插槽。

並測試,其中所有邊界的情況下,嘗試:

let ages = [ 50, 67, 75, 76, 25, 12, 26, 51, 99, 45, 0, 120, 16 ] 

然後:

print(subArrays) 

給出:

[[25,12,0,16] ,[50,26,45],[67,75,51],[76,99,120]]

+0

*我假設沒有漂浮物或負數。 –

+0

@ l'L'l OP的代碼顯示結果是一個'Int'數組,因此我假設這個年齡數組也是'Int'。沒有人有負面的年齡。但我的答案實際上將值從-23到-1放入第一個結果數組中。 – rmaddy

+0

是的,雖然取決於你如何看待它,但一些科學家可能會爭辯說有人(不是活的)也可能是11,000年以前的......但也許這是對於這個問題的解決辦法:) –

2

不依賴於你的範圍的任何數學特性更寬泛的版本:

func split<T>(array: [T], ranges: [CountableClosedRange<T>]) -> [[T]] { 
    var result = Array(repeating: [T](), count: ranges.count) 

    for element in array { 
     if let subIndex = ranges.index(where: { $0 ~= element }) { 
      result[subIndex].append(element) 
     } 
    } 
    return result 
} 

let ages = [10, 20, 30, 40, 50, 60] 
let subarrays = split(array: ages, ranges: [0...25, 26...50, 51...75, 76...Int.max]) 

需要注意的是它不檢查重疊範圍。

+0

你需要傳遞更好的範圍來處理浮點年齡如果這是所需的。例如,如果使用了一系列「Float」年齡,樣本範圍將不會達到25.5。我只提到這一點,因爲你的答案的目標是處理其他類型。 – rmaddy

0

基於rmaddy的答案(實際上是相同的),但在一行內:

let subs = (0...3).map { sub in ages.filter { sub == min(($0 - 1)/25, 3) } } 
+0

這是一種浮華,但它很難閱讀和理解,它最終迭代4次而不只是一次。 – rmaddy