이 링크를 정리한 내용입니다.
생략한 부분도 있고,
잘못이해한 부분이 있을 수 있으니 원문을 꼭 참고하세요.
데이터를 날짜 순으로 정렬을 시켜놨다.
그런데 동일한 날짜 때문에
테이블이 re-rendering이 될 때 마다 동일한 날짜의 row들이 서로 자리를 슥삭슥삭 바꿔대는 이슈가 발생했다.
시간이 없어서
sort의 원리와 속성을 모른채로 감으로다가,
급하게 아래 코드를 짜서 다중 조건 정렬을 했다.
날짜와 로컬 인덱스를 기준으로 다중 정렬
const dateAndLocalDescending = (a, b) => { let dateA = new Date(a["record_date"]).getTime(); let dateB = new Date(b["record_date"]).getTime(); let indexA = a["local_index"]; let indexB = b["local_index"]; return dateA > dateB ? -1 : indexA > indexB ? 0 : 1; };
성공하고도 찜찜해서,
'나중에 이거 꼭 자세히 알아보고 리팩토링 해야지!' 했는데
그게 오늘이다.
그래서 일반적으로 생각하는 문자열 정렬 순서와는 다를 수 있다.
그리고 주의할 건,
복사본을 return 하는게 아니라
데이터를 온존하고 싶다면 복사해서 정렬해야겠다.
- 0보다 작은 경우, a를 b보다 낮은 인덱스로 정렬한다.
- 0인 경우, a와 b를 서로 변경하지 않고 넘어간다.
- ECMAscript가 해당 동작을 보장하지 않아 모든 브라우저가 이처럼 동작하지는 않는다.
- 0보다 큰 경우, b를 a보다 낮은 인덱스로 정렬한다.
compareFunction(a, b)은 요소 a와 b의 특정 쌍이 두 개의 인수로 주어질 때 항상 동일한 값을 반환해야합니다. 일치하지 않는 결과가 반환되면 정렬 순서는 정의되지 않습니다.
라고 원문에 쓰여있는데 이건 잘 이해가 되지 않는다.
(알고 계신 분은 답글 부탁드립니다.)
function compare(a, b) { if (이 조건에 따르면 a가 b보다 작다.) { return -1; } if (이 조건에 따르면 a가 b보다 크다.) { return 1; } // a가 b와 동일한 경우! return 0; }
다음 함수는 배열을 오름차순으로 정렬한다.
(infinity 및 NaN 이 포함되어 있지 않은 경우)
function compareNumbers(a, b) { return a - b; }
let numbers = [4, 2, 5, 1, 3]; numbers.sort(function(a, b) { return a - b; }); console.log(numbers); // [1, 2, 3, 4, 5]
var items = [ { name: 'Edward', value: 21 }, { name: 'Sharpe', value: 37 }, { name: 'And', value: 45 }, { name: 'The', value: -12 }, { name: 'Magnetic', value: 13 }, { name: 'Zeros', value: 37 } ]; // value 기준으로 정렬 items.sort(function (a, b) { if (a.value > b.value) { return 1; } if (a.value < b.value) { return -1; } // a must be equal to b return 0; }); // name 기준으로 정렬 items.sort(function(a, b) { var nameA = a.name.toUpperCase(); // ignore upper and lowercase var nameB = b.name.toUpperCase(); // ignore upper and lowercase if (nameA < nameB) { return -1; } if (nameA > nameB) { return 1; } // 이름이 같을 경우 return 0; });
배열내의 요소마다 여러 번 호출되어,
높은 오버헤드가 발생할 수 있다.
비교함수가 복잡해지고, 정렬할 요소가 많아질 경우
임시배열을 하나 만들어,
map메소드를 이용해 실제로 정렬할 요소만 추려넣어 정렬 시킨 뒤,
이 리턴값을 이용해 실제 정렬을 하는
map을 사용한 정렬은 다음과 같다.
// 소트 할 배열 let list = ['Delta', 'alpha', 'CHARLIE', 'bravo']; // 임시 배열은 위치 및 정렬 값이있는 객체를 보유합니다. let mapped = list.map(function(el, i) { return { index: i, value: el.toLowerCase() }; }) // 축소 치를 포함한 매핑 된 배열의 정렬 mapped.sort(function(a, b) { return +(a.value > b.value) || +(a.value === b.value) - 1; }); // 결과 순서를 위한 컨테이너 let result = mapped.map(function(el){ return list[el.index]; });
이제 정렬 리팩토링을 하려고 하는데,
아무래도 데이터가 많다보니
sort 보다는 map을 사용한 방식으로 리팩토링 해야겠다.