2017-02-27 2 views
1

Ich habe eine Reihe von Altersgruppen.Aufteilen eines Arrays in Subarrays durch Variablen Wert

Ich möchte das Array in 4 Untergruppen nach dem Alterswert aufteilen.

A -> 0 ... 25

B -> 26 ... 50

C -> 51 ... 75

d -> 76 +

I Es ist kein Problem, das Array zu durchlaufen und an verschiedene Arrays nach dem Alterswert anzuhängen.

  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) 
       } 
      } 

Meine Fragen ist: Gibt es einen sauberen Weg, dies zu tun mit map, split oder einer anderen Funktion.

Dank

+1

Ist es sicher anzunehmen, bedeuten Sie 'd -> 76 +' statt 'd -> 85 +'? – rmaddy

Antwort

3

Diese verwendet nicht map oder etwas Besonderes, aber Sie switch leicht beseitigen können:

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

Die Verwendung von min sichergestellt, dass alle Werte von 76 und größer in den letzten einschieben.

Und zu testen, mit allen Grenzfällen, versuchen:

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

Und dann:

print(subArrays) 

Gibt:

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

+0

* keine Gleitkommazahlen oder negative Zahlen, nehme ich an. –

+0

@ l'L'Der OP-Code zeigt, dass die Ergebnisse ein Array von 'Int' sind, also nehme ich an, dass das Array von Altern auch' Int' ist. Und niemand hat ein negatives Alter. Aber meine Antwort setzt Werte von -23 bis -1 in das erste Ergebnis-Array. – rmaddy

+0

Stimmt, obwohl, je nachdem, wie Sie es betrachten, könnten einige Wissenschaftler argumentieren, dass jemand (nicht leben) 11.000 Jahre alt sein könnte ... aber vielleicht ist das für diese Frage weg :) –

2

Eine generische Version, die auf jeder mathematische Eigenschaft Ihrer Bereiche nicht davon ab:

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]) 

Beachten Sie, dass es nicht für überlappende Bereiche überprüft.

+0

Sie müssten in besseren Bereichen umgehen zu behandeln Floating Point altert, wenn das gewünscht wurde. Die Sample-Bereiche würden zum Beispiel 25,5 nicht erreichen, wenn ein Array von Float-Altern verwendet würde. Ich erwähne das nur, weil das Ziel Ihrer Antwort darin besteht, andere Arten zu behandeln. – rmaddy

0

auf rmaddy Antwort Basierend (praktisch gleich), aber innerhalb einer Zeile:

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

Dies ist eine Art von Slick, aber es ist schwer zu lesen und zu verstehen, und es endet damit, das Zeitalter-Array 4 mal statt nur einmal zu wiederholen. – rmaddy

Verwandte Themen