본문 바로가기

RPA

[UiPath] Array에서 최빈값 구하기

문제가 생겼다.

 

이번엔 나 말고 동료분이다.

Array나 List에서 최빈값을 구하고 싶다고 한다. 최빈값이란.. 최고로 빈번하게 나오는 값이라는 뜻이다.
예를 들어 {"A","B","C","A"}가 있으면 A를 찾고싶다는 것이다.

 

제일 처음 떠올랐던 생각은 loop를 돌면서 각 value가 몇번씩 나왔는지 체크하고 그 중 제일 큰것을 뽑아내는 것.. 너무 복잡하고 번거로워서 시도해보지 않았다.

 

두번째는 method를 찾아내는 것.... 못찾았다...

 

마지막으로 나보다 더 나은 사람의 지식을 빌려보았다.

forum.uipath.com/t/how-to-find-the-count-of-each-element-in-an-array-that-is-duplicated-and-print-that-value-in-output/107142 //How to find the count of each element in an array that is duplicated and print that value in output?
forum.uipath.com/t/extract-dictionary-datatable-value-using-linq/159309/3 //Extract Dictionary / datatable value using linq

위의 두 글을 보고 실마리를 잡았다. 각 value의 count를 dictionary 형태로 저장한 후 dictionary의 value가 가장 큰 key값을 뽑아내기로 했다. key 값으로 value를 뽑아낼 수 있다면 value로도 key를 뽑아낼 수 있지 않을까.. (key와 value는 속성이 꽤 다르지만)하는 생각에 시도 해보았고 성공했다! 

우선 결과는 다음과 같이 원하는대로 잘 나왔다

 

Variables 정보이다

Name Variable type
dict Dictionary<String, Int32>
arrString String[]
strResult String

 

상세 코드는 다음과 같다

No To Value
1 arrString {"A","B","C","A"}
2 dict (From item in arrString Group item By value = item Into GroupResult = Group Select GroupResult).ToDictionary (Function (x) CStr (x (0)), Function (y) CInt (y.Count))
3 strResult dict.Where(Function (a) a.Value.Equals(dict.Values.Max)).Select(Function(a) a.Key).FirstOrDefault()

1. String[]이다. type이 변경되어도 상관없다.
2. Array를 dictionary로 변경한다. array의 type을 바꿔줄 것이라면 Function (x) CStr(x (0)),... 부분도 type에 맞게 변경해주어야 한다. 뒤의 CInt는 Count가 들어갈 것이어서 바꾸면 안된다.
3. dict 최빈값의 key를 저장한다. value이기 때문에 값이 여러개가 나올 수 있다. .FirstOrDefault()를 사용해서 처음의 값을 사용한다. 만약 array가 {"A","A","B","B","C"}라면 결과는 A로 나온다.

사실 2번의 과정에서 굳이 dict로 바꾸지 않고 최빈값을 바로 뽑아낼 수 있을 것 같지만 저 코드에서 어디를 건드려서 어떻게 해야 뽑아낼 수 있을지는 감이 잡히질 않는다.. 조금 더 뜯어본 뒤 dictionary도 걷어낼 수 있는 방법을 찾고 싶다.

 

처음에는 한번의 assign으로 끝내고 싶어서 dict를 선언하지 않고 쭉 썼다가 다음에 열어보면 나도 못알아보겠다 싶어서 부리나케 dict를 선언해서 나름 쾌적하게 사용할 수 있도록 했다. 앞으로 변수 선언을 아끼지 말아야지...