on
[Flutter/Dart] 확장 함수를 사용한 리스트 중복 체크
[Flutter/Dart] 확장 함수를 사용한 리스트 중복 체크
반응형
확장 함수를 사용한 리스트 중복 체크
이전에 Map에 확장함수(Extension method)를 만들어보자에서 간단하게 Map 의 확장함수 fetch 를 만들어서, 널 처리 및 타입 변환 등의 처리를 했었다. 이번에는 확장함수를 사용해서 배열의 중복 체크를 해보자.
결과부터 확인해보자. Dartpad에서 아래의 코드를 돌려보면 정상적으로 값이 출력되는 것을 확인할 수 있다. 간단하지만 자바스크립트로 구현했을때랑은 조금 다른데, 하나씩 살펴보도록 하자.
extension ListExtension on List { bool isSameListWith(List other) { bool result = true; if (length == other.length) { asMap().forEach((index, value) { if (other[index] != value) { result = false; } }); } else { result = false; } return result; } } void main() { List listA = [1, 2, 3, 4, 5]; List listB = [1, 2, 3, 4, 5]; List listC = [1, 2, 3, 4]; List listD = ['a', 'b', 'c', 'd']; print("listA is same with listB?: ${listA.isSameListWith(listB)}"); print("listA is same with listC?: ${listA.isSameListWith(listC)}"); // print("listA is same with listD?: ${listA.isSameListWith(listD)}"); }
asMap()을 사용한 index와 value의 분류
Javascript였다면 collection 메서드의 두 번째 인자가 index이므로, 굳이 이런 절차는 필요하지 않다. 게다가 asMap() 을 통해 Map으로 변환하고나면 사용할 수 있는 collection 메서드가 제한되므로, 딱히 편리하지도 않다.
fold를 썼으면 편했을텐데
Map 이 지원하는 메서드를 확인하려면 Map을 페이지를 참조하자.
List.asMap() 을 사용하면 index 를 키로, 리스트의 요소를 값으로 변환하게 된다. 이렇게 index 에 대한 접근을 할 수 있다. 먼저 배열의 길이를 체크한다. 배열의 길이가 다르면 당연히 다른 배열이며, 길이를 체크하지 않으면 RangeException 이 발생할 수 있으므로 주의하자. (다른 사람들은 모르겠지만 나는 자주 깜빡한다.)
이제 forEach 를 통해 서로 다른 배열을 발견하면, 플래그를 false 로 변환한다.
제네릭을 사용한 타입 체크
확장함수 선언 시 제네릭을 사용하여 List 의 타입과 isSameListWith 메소드에 인자로 전달되는 other 의 타입을 T 로 고정시켰다. 이 내용은 생략하더라도 런타임에서 각 리스트의 요소를 비교하다 false 를 반환하게 된다. 하지만 인자의 타입을 T 로 고정시키면 컴파일 타임에 other 와 원본 List 의 타입을 비교하여 에러를 발생시킨다. 애시당초 List 과 List 는 다른 리스트이며, 비교할 이유도 없으니 컴파일 타임에 걸러낼 수 있는 셈이다.
결론
이번에는 확장함수를 통해 두 배열이 서로 다른 리스트인지 체크하고, 나아가서 제네릭을 사용해 타입을 고정시킴으로서 컴파일 타임에 타입과 관련된 에러를 걸러낼 수 있도록 작성해봤다. :)
반응형
from http://zerodice0.tistory.com/232 by ccl(A) rewrite - 2021-09-13 10:27:16