Power Automateでは組み込みのソート操作がありません。
このため、2018年にはApply to each (ループ)を利用したソート方法が考案されました。[1]
このほかにも、最近では、Excelのテーブルを経由してデータをソートする方法も考えられています。[2]
これらの方法を @johnnliu に教えてもらって、チャットしていたら、『新しい方法を思いついた!』[3] と言い出したので、悔しくなって自分も新しい方法を考えていた結果、ループを利用しないソートの方法が見つかったので紹介します。
###Refs
- How to implement Sort with Microsoft Flow in 3 actions within a loop
- Sort an array in Power Automate in 3 easy steps
- Implementing a fast sort with Microsoft Flow using Parallel Compute
ループなしソートの方法
今回は文字の配列を対象に、ソートのコンセプトを説明します。
先にFlowですが、お手軽3ステップです。こういう基本的な操作は短いほど応用効くので、いいですね。
AtoZ Array
これがソート順を決めています。今回はa~Zの昇順でソートしているのですが、逆順にする場合には[z,Z,y,Y,...,a,A]のような配列を作ればよいです。
手で配列を作るのは大変なので、文字列を1文字ずつに分割する方法 を利用します。
Selectアクションを利用していて、Fromは
range(0,length('aAbBcCdDeEfFgGhHiIjJkKlLmMoOpPqQrRsStTuUvVwWxXyYzZ'))
Mapには
substring('aAbBcCdDeEfFgGhHiIjJkKlLmMoOpPqQrRsStTuUvVwWxXyYzZ',item(),1)
を入力しています。
Filter array
概念図の操作を実現するために、Filterアクションを利用します。
FilterのFromはAtoZ Arrayです。
Conditionが最も重要ですが、
intersection(json(concat('["', item(), '"]')), outputs('Initial_Array'))?[0]
Intersectionの結果がnullでないものでフィルターします。
ちょうど上の図の点線で書いた四角をフィルターして除去しているイメージです。
[2020/3/11 追記]
Intersection()=null は、数式使わずに
条件としてひっくり返したようなcontainsで代用できました。
(From はAtoZ arrayだけど、比較するのは 未ソート配列が、item()を含むかどうか)
実行速度比較
大文字小文字を含む40文字で試してみました。
十分な速度(0s)で処理が実行できていることが分かります。
注意事項
このソートでは、元の配列に重複がないこと、空がないことを前提にしています。元の配列に重複がある場合には、1:NのLeft-joinをxpathを利用することで実現できますが、長くなるので次回以降ご紹介します。