2016-05-01 14 views
2

モーションセンサからの走行トリップをフィルタリングするコードを書いています。自信を持って、自動車イベント 次のオブジェクトに基づくフィルタ配列

  • の最初の発生を検出

    • 同じに以下のすべてのモーションイベントを追加します。以下に基づいて、ネストされた配列に部分配列を追加するために、私はこれを行うための最善の方法を考え出したですそうでなければ言う最初の確信のある観察までイベントの配列。

      automotive confidence 2 //Add 
      automotive confidence 2 //Add 
      automotive confidence 2 //Add 
      walking confidence 2 //Add the sub-array to the master array and start over on the next confident automotive event. 
      

      例えば

    現在、私はそれをこのようにやっている:

     //Remove all uncertain values. 
         let confidentActivities = activities!.filter{$0.confidence.rawValue == 2} 
    
         var needsNew = true 
         var automotiveActivities:Array<Array<CMMotionActivity>> = Array() //Master array to contain subarrays of automotiveactivity arrays 
         var automotiveActivitySession:Array<CMMotionActivity> = Array() 
         for activity in confidentActivities { 
          if activity.automotive && (!activity.cycling && !activity.running && !activity.walking){ 
           if needsNew { 
            needsNew = false 
           } 
           automotiveActivitySession.append(activity) 
          } else { 
           if !needsNew { 
            //If user is no longer in car, store a cpoy of the session and reset the array 
            automotiveActivities.append(Array(automotiveActivitySession)) 
            automotiveActivitySession = [] 
            needsNew = true 
           } 
          } 
         } 
    

    このソリューションは非常にエレガントではありません。 SwiftのArray.filter{}を使用してこの並べ替えをよりきれいにする方法はありますか?

  • 答えて

    1

    フィルタは実行しませんが、reduceを使用できます。

    以下の例では、アレイのアレイ内部配列に連続"A" S(自動車イベントを表す)のランを収集する方法を示しています。

    let data = ["A","A","A","B","A","A","B","A","A","A","A","B","B","B","A","B","A","A","A","A","A","A","B","A"] 
    var res = [[String]]() 
    _ = data.reduce("") { (last: String, current: String) in 
        if current == "A" { 
         if last != "A" { 
          res.append([String]()) 
         } 
         res[res.count-1].append(current) 
        } 
        return current 
    } 
    print(res) 
    

    前値は最初ようreduceの関数に渡されます。パラメータ。これにより、関数は現在のリストに追加するか新しいリストを開始するかを決定することができます。

    次のようにこの実験の結果は次のとおりです。

    [ ["A", "A", "A"] 
    , ["A", "A"] 
    , ["A", "A", "A", "A"] 
    , ["A"] 
    , ["A", "A", "A", "A", "A", "A"] 
    , ["A"]] 
    
    0

    あなたはかなり解決後にしている場合は、あなたがこれを行うにはsplitを使用することができます。セパレータとみなされるべき条件については、それを提供するだけです。あなたのケースでは、これは自動車のものではない動きイベントです。ここ

    let arr = ["A","A","A","B","A","A","B","A","A","C","A","B","D","B","A","B","A","E","A","A","F","A","B","A","B"] 
    let split = arr.split {$0 != "A"} // insert your condition for whether the given element should be considered a 'seperator' 
    

    $0(それが反復処理として)配列の要素のための匿名のクロージャ引数です。それほどエレガントではないが、名前をより明示的にするために、クロージャをいつでも展開することができます。これは非常に似ArraySlicesの配列を返します

    let split = arr.split {element in 
        return element != "A" 
    } 
    

    :たとえば

    [ 
        ArraySlice(["A", "A", "A"]), 
        ArraySlice(["A", "A"]), 
        ArraySlice(["A", "A"]), 
        ArraySlice(["A"]), 
        ArraySlice(["A"]), 
        ArraySlice(["A"]), 
        ArraySlice(["A", "A"]), 
        ArraySlice(["A"]), 
        ArraySlice(["A"]) 
    ] 
    

    をあなたがそれらをArrays明示的になりたい場合は、単にその後mapを使用することができます。

    let split = arr.split {$0 != "A"}.map{Array($0)} 
    

    返品:

    [ 
        ["A", "A", "A"], 
        ["A", "A"], 
        ["A", "A"], 
        ["A"], ["A"], 
        ["A"], 
        ["A", "A"], 
        ["A"], 
        ["A"] 
    ] 
    
    関連する問題