5
0

More than 1 year has passed since last update.

【UiPath】自然順ソート(Natural Sort Order)してみる

Posted at

はじめに

この投稿は、RPAツール「UiPath」での 実装例 について記事です。

はじめに

この投稿は、RPAツール「UiPath」での API呼び出し例 の記事です。

この記事は「UiPath Friends もくもく会 2021年9月開催 2021-09-25(土)9:00 - 12:00」で書きました。

自然順ソート(Natural Sort Order)とは

自然順ソートとは、数字部分の大小を良い感じに解釈してくれるソートのことです。
WindowsExplorerの「名前順の並び替え」は、この自然順ソートで表示されています。

image.png

通常のソートとは違い、数字部分を自然に解釈してくれて、見やすくなっています。

UiPathで自然順ソートする

上述の通り、通常のソートでは自然順になりません。

.NETでソートする場合、StrCmpLogicalW を使ってソートをするのが良くある方法ですが、
「shlwapi.dll」をインポートしないといけないため、ちょっと面倒です。

なので、InvokeCodeで実装してみます。
引数は「In/Out」で配列型を渡します。

'// Argument
' aryIO

'// Function
Dim PartCompare As Func(Of String, String, Integer) = 
    Function(left As String, right As String) As Integer
        Dim x, y As Integer
        If Not(Integer.TryParse(left, x)) Then
            Return left.CompareTo(right)
        ElseIf Not(Integer.TryParse(right, y)) Then
            Return left.CompareTo(right)
        End If
        Return x.CompareTo(y)
    End Function

'// Function
Dim NaturalCompare As Func(Of String, String, Integer) = 
    Function(x As String, y As String) As Integer
        Dim table As New System.Collections.Generic.Dictionary(Of String, String())
         If x = y Then
             Return 0
         End If
         Dim x1, y1 As String()
         If Not(table.TryGetValue(x, x1)) Then
            x1 = System.Text.RegularExpressions.Regex.Split(x.Replace(" ", ""), "([0-9]+)")
            table.Add(x, x1)
        End If
         If Not(table.TryGetValue(y, y1)) Then
            y1 = System.Text.RegularExpressions.Regex.Split(y.Replace(" ", ""), "([0-9]+)")
            table.Add(y, y1)
        End If

        Dim i As Integer = 0
            While i < x1.Length AndAlso i < y1.Length
                 If x1(i) <> y1(i) Then
                     Return PartCompare(x1(i), y1(i))
                 End If
            i += 1
        End While

        If y1.Length > x1.Length Then
            Return 1
        Else If x1.Length > y1.Length Then
            Return -1
        Else
            Return 0
        End If
        Return 0
    End Function

'// Main
For idxA As Integer = 0 To UBound(aryIO) -1
    For idxB As Integer = idxA + 1 To UBound(aryIO)
        If NaturalCompare(aryIO(idxA), aryIO(idxB)) > 0 Then
            Dim wrk As String = aryIO(idxB)
            aryIO(idxB) = aryIO(idxA)
            aryIO(idxA) = wrk
        End If
    Next
Next

配列を受け取り、ループしながら前後で値を比較しています。
比較の際には、数値部分を切り出して桁数を合わせながら実施しています。

普通、.NETでソートを定義する場合は「IComparableインターフェース」を実装したクラスを「Array.Sortメソッド」に渡して処理しますが、UiPathではクラス定義が出来ないので、上記のように前後比較して並び替えています。

終わりに

いかがでしたでしょうか。実装時に役立てば幸いです。
この記事が参考になったら、 LGTMをお願いします。閲覧ありがとうございました。

5
0
0

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
5
0