Skip to content

Instantly share code, notes, and snippets.

@KentarouKanno
Last active August 26, 2016 13:54
Show Gist options
  • Save KentarouKanno/8a88f9f0f4f9d1b02fa8 to your computer and use it in GitHub Desktop.
Save KentarouKanno/8a88f9f0f4f9d1b02fa8 to your computer and use it in GitHub Desktop.
reduce

Array reduce

★ 配列の中の2要素から計算して、その結果を返す。
さらにその結果から次の要素を計算して結果を返し、それを配列分繰り返した値を返す。

let numList = [1 ,2 ,3 ,4 ,5]

let value = numList.reduce(0){(a:Int, b:Int) -> Int in
    return a + b
}

//=> value = 15

// ※ 上記を省略したコード
let value = numList.reduce(0){$0 + $1}

// 以下も同じ値になる
let value = numList.reduce(0, combine: {a, b in a + b})
let value = numList.reduce(0, combine: {$0 + $1})
let value = numList.reduce(0, combine: +)

★ 配列の中身をカンマ区切りの文字列にする

let colors = ["red","green","blue","black"]

let colorStr = colors.reduce(""){
    
    if $0 != "" {
        // 2個目移行
        return $0 + "," + $1
    } else {
        // 最初の文字の場合
        return $1
    }
}

print("colorStr = \(colorStr)")
//=> colorStr = "red,green,blue,black"

//  以下も同じ
let colorStr = colors.joinWithSeparator(",")
//=> colorStr = "red,green,blue,black"

★ 配列の中で一番小さい値を求める

let numbers = [10, 5, 9, 300, 6, 99, 7, 8, 9, 10]

// Int.maxより小さい場合はその数値を返す
let minValue = numbers.reduce(Int.max) {
    
    if $0 > $1 {
        // 配列から取り出した値が小さい場合
        return $1
    } else {
        return $0
    }
}

print("minValue = \(minValue)")
//=> minValue = 5


//  以下も同じ
let minValue = numbers.minElement()
//=> minValue = 5

★ 多次元配列同士で比較する対象の配列が全て含まれているかチェックする

var x:[[String]] = [["a", "b"], ["c", "d"], ["e", "f"], ["g", "h"], ["i", "j"], ["i", "aj"]]
var y:[[String]] = [["a", "b"], ["c", "d"], ["e", "f"]]


// resultFlgには「y」の要素が全て「x」に含まれている場合は'true', 含まれていない場合は'false'が入る

// (true)は初期値, forwardFlgは前のBool値が入ってくる(最初は初期値'true')
// elementYは「y」の要素が毎回入ってくる 1: ["a", "b"], 2: ["c", "d"], 3: ["e", "f"]

let resultFlg = y.reduce(true) { (forwardFlg, elementY) -> Bool in
    
    // 前のフラグが'false'だった場合は、含まれていない値があったので'false'を返す
    if !forwardFlg {
        return false
    }
    
    // xの配列の要素を一つづつ取り出す
    for elementX in x {
        if elementY == elementX {
            // elementYが「x」に含まれていたので'true'を返す(次のforwardFlgは'true'になる)
            return true
        }
    }
    
    // 今回のelementYは「x」に含まれていなかったので'false'を返す(次のforwardFlgは'false'になる)
    return false
}

resultFlg
//=> true

★ reduceを使用してのUITableViewのSection分け

// ロジック前
["2016/08/26", "2016/08/26", "2016/08/26", "2016/08/01", "2016/07/27", "2016/05/26",  "2016/05/25", "2015/02/21"]

// ロジック後
// Section配列
 ["2016/08", "2016/07", "2016/05", "2015/02"]
 
// Row配列
[["26", "26", "26", "01"], ["27"], ["26", "25"], ["21"]]
var dataArray = ["2016/08/26", "2016/08/26", "2016/08/26", "2016/08/01", "2016/07/27", "2016/05/26",  "2016/05/25", "2015/02/21"]

var resultArray = dataArray.reduce(([],[])) { (resultTuple, str) -> ([String], [[String]]) in

    var result1 = resultTuple.0
    var result2 = resultTuple.1

    let yearStr = (str as NSString).substringToIndex(7)
    let dayStr  = (str as NSString).substringFromIndex(8)

    if !result1.contains(yearStr) {
        result1 += [yearStr]

        let array = [dayStr]
        result2.append(array)

    } else {
        result2[result2.count - 1].append(dayStr)
    }
    return (result1, result2)
}

resultArray.0
//=> ["2016/08", "2016/07", "2016/05", "2015/02"]
resultArray.1
//=> [["26", "26", "26", "01"], ["27"], ["26", "25"], ["21"]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment