5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have 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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?