🔄

SORACOM Fluxでループを使って配列を処理する

に公開

やりたいこと

SORACOM Fluxでループを使って配列を処理するためのtipsを紹介します。
以前書いたblogの中でSORACOM Fluxは未知の長さの配列を扱うのが難しいと書きましたが、ループを使うことで解決できることがわかりました。

やり方

SORACOM Fluxの設定をしていきます。
SORACOM Flux is 何?という方はこちらをご覧ください。

設定の概要

alt text
以下のようなことを実施するフローを作っていきます。
数字は、上記のフローの説明をした図中の吹き出しの番号に合わせています。

  1. トリガ設定
    イベントソース : API/マニュアル実行
    出力チャネル: API Cnannel
    今回はループの機能確認を行うので、API/マニュアル実行を選択します。
    実際のアプリケーションで使う場合は適切なトリガを選択してください。

  2. 簡易物体検出アクション
    入力チャネル: API Channel

    APIアクションブロックの設定

    設定内容

    大項目 詳細項目 設定値 備考
    CONDITION アクションの実行条件 空欄
    CONFIG 画像URL https://blog.soracom.com/ja-jp/wp-content/uploads/2024/07/soracam-team-1-1024x683.jpg SORACOM 公式ブログの画像を拝借
    OUTPUT アクションのアウトプットを別のチャネルに送信する 有効
    OUTPUT 送信先チャネル Output チャネル名称は自由

    設定画面(例)
    alt text

    出力されるJSON

    {
      "person": 6,
      "car": 0,
      "bus": 0,
      "truck": 0,
      "cat": 0,
      "dog": 0,
      "objects": [
        {
          "location": [
            0.6609779,
            0.17652985,
            0.9373262,
            0.9943735
          ],
          "score": 0.8904824,
          "label": "person",
          "ts": "2025-05-07T01:48:41Z"
        },
        {
          "location": [
            0.37141305,
            0.3185921,
            0.5251937,
            0.969292
          ],
          "score": 0.8751769,
          "label": "person",
          "ts": "2025-05-07T01:48:41Z"
        },
        {
          "location": [
            0.04004524,
            0.21790065,
            0.21095791,
            0.84099317
          ],
          "score": 0.8547369,
          "label": "person",
          "ts": "2025-05-07T01:48:41Z"
        },
        {
          "location": [
            0.4620108,
            0.37004647,
            0.6945141,
            0.9970469
          ],
          "score": 0.83913076,
          "label": "person",
          "ts": "2025-05-07T01:48:41Z"
        },
        {
          "location": [
            0.23511018,
            0.3791213,
            0.39225024,
            0.8577786
          ],
          "score": 0.8179504,
          "label": "person",
          "ts": "2025-05-07T01:48:41Z"
        },
        {
          "location": [
            0.13871717,
            0.3871962,
            0.27425474,
            0.8432603
          ],
          "score": 0.7499229,
          "label": "person",
          "ts": "2025-05-07T01:48:41Z"
        },
        {
          "location": [
            0.4429141,
            0.47117797,
            0.48522377,
            0.6288479
          ],
          "score": 0.2793063,
          "label": "tie",
          "ts": "2025-05-07T01:48:41Z"
        },
        {
          "location": [
            0.39311492,
            0.4475629,
            0.42104053,
            0.6097326
          ],
          "score": 0.2578054,
          "label": "tie",
          "ts": "2025-05-07T01:48:41Z"
        }
      ]
    }
    

    出力チャネル: Output

  3. ループカウンタ(num)とループ上限(length)と分解したい配列をセット

    入力チャネル:Output

    repubrishブロックの設定

    入力されるpayload

    {
      "person": 6,
      "car": 0,
      "bus": 0,
      "truck": 0,
      "cat": 0,
      "dog": 0,
      "objects": [···]
    }
    

    objectsの中身は省略しています。

    設定内容

    大項目 詳細項目 設定値 備考
    CONDITION アクションの実行条件 空欄
    CONFIG データを変換する ✅️
    CONFIG Content Type application/json デフォルト設定
    CONFIG Content {
    "num" : 0,
    "length" : ${len(payload.objects)},
    "objects" : ${payload.objects}
    }
    objectsで出力される配列の長さを計算する
    len()も含めて${}の中にいれる。
    len(${payload.objects})としたくなるが、それは間違い。
    OUTPUT アクションのアウトプットを別のチャネルに送信する 有効
    OUTPUT 送信先チャネル Output Channel

    alt text

    出力されるJSON

    {
        "num":0,
        "length":8,
        "objects":[···]
    }
    

    objectsの中身は省略しています。

    出力チャネル: Output Channel

  4. numのインクリメントとpayload.objectsnum番目の要素の取り出し
    入力チャネル: Output Channel

    Repubishブロックの設定
    {
        "num":0,
        "length":8,
        "objects":[···]
    }
    

    objectsの中身は省略しています。

    設定内容

    大項目 詳細項目 設定値 備考
    CONDITION アクションの実行条件 payload.num < payload.length - 1 左記条件のときにはインクリメントをして出力を行う。
    CONFIG データを変換する ✅️
    CONFIG Content Type application/json デフォルト設定
    CONFIG Content {
    "num":${payload.num+1},
    "length": ${payload.length},
    "objects": ${payload.objects}
    }
    入力されたnumをインクリメントして出力する。
    インクリメントの+1${}内に書く。
    lengthobjectsはそのまま出力する。
    OUTPUT 送信先チャネル Output Channel 入力チャネルに戻して再びこのアクションに入ってくるようにループをかける
    {
        "num":1,
        "length":8,
        "objects":[···]
    }
    

    objectsの中身は省略しています。

    出力チャネル: Output Channel(このアクションへの入力チャネルと同じ)

  5. num番目の要素を通知
    入力チャネル: Output Channel

    Slack通知アクションの設定

    入力されるpayload

    {
        "num":0,
        // 1,2,3,4···とインクリメントされ、入ってくる
        "length":8,
        "objects":[···]
    }
    

    設定内容

    大項目 詳細項目 設定値 備考
    CONDITION アクションの実行条件 空欄
    CONFIG URL https://hooks.slack.com/servicesから始まるURL sebhookURLはこちらの方法を参照してして入手する
    CONFIG Payload ${payload.num} :
    ${payload.objects[payload.num]}
    1行目に番号を、2行目にpayload.objectsnum番目の要素をいれる
    OUTPUT アクションのアウトプットを別のチャネルに送信する 無効

    alt text

実行結果

以下のようにSORACOMのSlackに通知されます。
ただし、slackへ通知が届く順序は順不同となっているようです。
配列の並び順とリクエストの到達順序にシビアなアプリケーションでは注意が必要です。
alt text

なお、今回ループをかけたRepublishアクションに実行条件

payload.num < payload.length - 1

を設定していたのでこれがループ回数の上限となりましたが、この条件文を外した場合は10回でループが止まりまるようになっています。
長さ10以上の配列を処理したい場合は、Outputのチャネルに接続するRepublishアクションの設定を並行でもう一つ作成し、numの初期値を10にせっていして を行うようにしループを回すことで各要素への処理を行うことができるようになると思います。

{
    "num" : 10,
    "length" : ${len(payload.objects)},
    "objects": ${payload.objects}
}
GitHubで編集を提案

Discussion