はじめに
Twitterで見かけたブログで、Power Automateの配列をランダムにする方法が出ていました。この方法では、Azure FunctionsをHTTPアクションで呼び出して配列のランダム化を実行しています。
でもFunctionsを使うまでもないような気がしたので、方法を検討してみました。
結果としては比較的簡単な方法で順序をシャッフルした配列が生成できました。使ったアクションは「選択」「作成」のみです。
サンプルをGithubに置いてあります。インポートして試してみてください。
PowerApps365/ShuffleArray_sample.zip at master · mofumofu-dance/PowerApps365 · GitHub
準備
ここでは簡単のために、上の記事と同じ配列を入力にしておきます。なるべくセットアップは同一にしておくという目的で、 「変数の初期化」アクションでこの配列を作成しました。タイプは「アレイ」です。
[ { "Id": "@{guid()}", "Name": "Abdullah Hamed" }, { "Id": "@{guid()}", "Name": "James Montemagno" }, { "Id": "@{guid()}", "Name": "Jayme Singleton" }, { "Id": "@{guid()}", "Name": "Jeff Fritz" }, { "Id": "@{guid()}", "Name": "Jon Galloway" }, { "Id": "@{guid()}", "Name": "Nish Anil" } ]
ステップ1 : ランダムな整数の配列を生成する
まずはランダムな整数 (元の配列の行数) × 100個を含む配列を作ります。 ランダムな整数ならなんでもいいというわけではなく、あとあと配列のインデックスに使いたいので、 0~(元の配列の行数)−1 の範囲でランダムな整数を生成します。
つまり上の配列であれば行数は6なので、
[4,5,2,1,4,2,3,1,1,0.....]
のように0~5までの整数で作られる600行の配列です。
これを作るために「選択」アクションを利用します。選択アクションの入力はそれぞれ以下のように設定してください。
From
@{range(0,mul(length(variables('Arr')),100))}
Map
@int(string(rand(0,length(variables('Arr')))))
これで期待する配列が生成されました。
ステップ2 : 値の重複を排除する
ステップ1で作った配列は、当然ですが同じ数が何度も出てきます。この重複を排除するために union関数を利用します。
union関数では配列を2つ与えることで、2つの配列を統合し、重複を除いた結果を返してくれます。
ステップ1の「選択」アクションに続けて、「作成」アクションを追加し、以下を入力に入れてください。
@{union(body('Generate_random_array'),range(0,length(variables('Arr'))))}
『ステップ1で生成した配列』と、『0~(元の配列の行数)−1』を順に並べた配列 (この例では [0,1,2,3,4,5]
)をunionしています。これにより 重複が排除された0~(元の配列の行数)−1 の整数を含む整数配列 が生成されます。
ステップ3: ランダムな順番に並べる
最後に、ステップ2で得られた順番に元の配列をマッピングしてあげます。「選択」アクションを追加して、以下のように設定します。
From
@{outputs('Generate_random_order')}
Map
@variables('Arr')?[item()]
どういうことをやっているのかは、下図の右下にあるイメージを見てみてください。
おわりと補足
以上で配列から順番をシャッフルした配列をループもなく、Azure Functionsを使うこともなく、生成できました。
念のため、本当にランダムっぽいのかを確認してみました。
ここで紹介した操作を1000回ループさせてみて、生成された配列の先頭が、元の配列の何番目だったのかをカウントした結果です。
統計がそれほどないのでがたついていますが、まあまあ許容できる範囲かなという印象です。
こんな風に、比較的簡単な操作で配列をシャッフルすることができますので、ぜひ試してみてください。