2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SwiftのカスタムクラスArray操作その2(Sum)※解決!【メモ】

2
Last updated at Posted at 2014-11-13

SwiftのカスタムクラスArrayでプロパティの値を合計

SwiftのArray内に以下の様なクラスのオブジェクトが入っていたとして、任意のプロパティの合計を求める。

※末尾にNSArrayでの記法も書いておきます。(コメントありがとうございます!)

使用するカスタムクラス(!無しのプロパティに修正)

Cat.swift
class Cat:NSObject{
    var name:String
    var color:String
    var age:Int
    var score:Int

    init(data: (String,String,Int,Int)){
        name = data.0
        color = data.1
        age = data.2
        score = data.3
    }
}

テストデータ

テストデータを準備しておきます。

UseCat.swift
var all_cats:[Cat] = [Cat]()
all_cats.append(Cat(data:("タマ","白",10,10)))
all_cats.append(Cat(data:("コトロ","茶トラ",2,10)))
all_cats.append(Cat(data:("ミケ","三毛",3,10)))
all_cats.append(Cat(data:("チビトラ","茶トラ",4,10)))
all_cats.append(Cat(data:("タケチヨ","キジトラ",7,10)))
all_cats.append(Cat(data:("マリアンヌ","白",7,10)))

合計の処理

正式な記法

正式な記法だと以下のとおり。

UseCat.swift
let score_sum:Int = all_cats.reduce(0,{
    
    //sum=最終的な戻り値:return結果が次の繰り返しのsumとなる
    //task=Array内のオブジェクト:繰り返しのたびに要素がセットされる
    (var sum:Int, var cat:Cat) -> Int in
    
    //毎回Taskのpropertyの値を足し込むことで、property値のsumも可能
    return sum + cat.score
})

実行結果は以下のとおり

UseCat.swift
println("score sum=\(score_sum)\n")
【実行結果】
score sum=60

※省略した記法

前回同様に、引数の記述を省略して$0,$1として値を受け取ることができます。またreturn文を省略して直接処理結果をreturnすることができます。

UseCat.swift
let score_sum2:Int = all_cats.reduce(0, {
    $0 + $1.score
})

//結果確認
println("score sum=\(score_sum2)\n")
【実行結果】
score sum=60

 

Objective-Cと同様にNSArrayを使う場合

NSArrayのvalueForKeyPathというメソッドは非常に高機能で、値の合計などに使用することができます。

詳しくは、Apple KVC Programming Guideを参照のこと

UseCat.swift
let score_sum3
    = (all_cats as NSArray).valueForKeyPath("@sum.score") as Int
println(score_sum3)

 

※ただしSwift上からこのコードを利用する場合には、Array内のカスタムクラスの計算させたいプロパティには、Optional型やImplicitly Unwrapped Optional型は使えないようです。
(プロパティの型として?や!付きの宣言しているとvalueForKeyPathからは利用できない)

Cat.swift(エラーになる例)
class Cat:NSObject{
    var name:String!
    var color:String!
    var age:Int!
    var score:Int!

    //以下略
}
【実行結果】
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MyProject.Cat 0x999999999999> valueForUndefinedKey:]: this class is not key value coding-compliant for the key score.'

 

※以下は未解決時の記載

※うーん、このコードはうまく動かないです。エラーメッセージ的には配列内の要素がNSObjectとみなされていないようです。原因がわかる方いらっしゃいましたらコメントいただけると有難いです。
(NSKeyValueCodingプロトコルと関係がありそう)

(追記)
こっちは動くのはなぜだろう。@max,@min,@sum,@avgはダメ。@countとかは結局プロパティにアクセスしないからOKなのだろうか。

~~```swift:UseCat.swift
let score_count
= (all_cats as NSArray).valueForKeyPath("@count.score") as Int
println(score_count)

2
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?