2017-02-27 77 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