자바 스크립트의 array.sort () 메서드를 확장하여 다른 매개 변수를 수락하는 방법은 무엇입니까?
객체 배열을 정렬하려고합니다. 각 속성에 대해 사용자 지정 정렬 방법을 작성하지 않는 것이 좋습니다.
어쨌든 array.sort()
추가 매개 변수를 받아들이도록 내장 메서드를 확장하여 정렬 할 속성을 설명 할 수 있습니까? 예 :
array.sort(function(a, b, attr) { return a.attr - b.attr; }, 'name');
속성 이름을받는 함수 생성기를 작성합니다.
function propComparator(prop) {
return function(a, b) {
return a[prop] - b[prop];
}
}
arr.sort(propComparator('name'));
나중에 사용하기 위해 직접 또는 매개 변수로 분류기를 저장할 수도 있습니다.
var compareNames = propComparator('name');
var compareFoos = propComparator('foo');
...
arr.sort(compareNames);
takesComparator(compareFoos);
ES6 용으로 업데이트되었으며 실제로 다른 유형에서 작동하도록합니다.
참고 sort
하거나 바람직하지 않을 수도에서 적절한 종류.
const arr = [
{ name: 'John', age: 92 },
{ name: 'Dave', age: 42 },
{ name: 'Justin', age: 3 }
]
const propComparator = (propName) =>
(a, b) => a[propName] == b[propName] ? 0 : a[propName] < b[propName] ? -1 : 1
arr.sort(propComparator('name'))
console.log("By name", arr)
arr.sort(propComparator('age'))
console.log("By age", arr)
이것이 당신이 찾고있는 것입니까?
function sortByProperty(array, propertyName) {
return array.sort(function (a, b) {
return a[propertyName] - b[propertyName];
});
}
var sortedByName = sortByProperty(myArray, "name");
프로토 타입을 사용하여 문자열과 숫자를 올바르게 비교
Array.prototype.sortAttr = function(attr,reverse) {
var sorter = function(a,b) {
var aa = a[attr];
var bb = b[attr];
if(aa+0==aa && bb+0==bb) return aa-bb; // numbers
else return aa.localeCompare(bb); // strings
}
this.sort(function(a,b) {
var result = sorter(a,b);
if(reverse) result*= -1;
return result;
});
};
예
var data = [
{name: "Josh", age: 18},
{name: "John", age: 17},
{name: "Bob", age: 20},
{name: 0, age: "error"}
];
data.sortAttr("name");
// data is now sorted by name
어쨌든 내장 array.sort () 메서드를 확장하여 추가 매개 변수를 허용 할 수 있습니까?
위의 모든 답변이 좋습니다. 하지만 부분 기능에 대한 정보를 추가 할 생각
추가 정보를 원하시면 MDN과의 결합을 참조 일부 기능 또는 존 레식 - 부분적인 기능을
MDN의 예 :
function list() {
return Array.prototype.slice.call(arguments);
}
var list1 = list(1, 2, 3); // [1, 2, 3]
// Create a function with a preset leading argument
var leadingThirtysevenList = list.bind(undefined, 37);
var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]
다음은 Google Closure 의 예입니다.
goog.partial = function(fn, var_args) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
// Prepend the bound arguments to the current arguments.
var newArgs = Array.prototype.slice.call(arguments);
newArgs.unshift.apply(newArgs, args);
return fn.apply(this, newArgs);
};
};
이 기능을 사용하려면
var fn=goog.partial(numberCompare,sortField,sortDirection);
myarray.sort (fn);
var numberCompare = function (sortField,sortDirection,value1,value2){
// sort code goes here
}
누군가 오름차순이 필요한 경우, 여기에 반대 옵션이있는 DaveNewton의 솔루션이 있습니다.
const sorton = (prop, asc=0) => {
if(!asc) return (a, b) => a[prop] == b[prop] ? 0 : a[prop] < b[prop] ? -1 : 1
else return (b, a) => a[prop] == b[prop] ? 0 : a[prop] < b[prop] ? -1 : 1
}
arr.sort(propComparator('age', 1))
실제로 확장
실제로 확장하기 위해 Array.prototype.sort
몇 가지 옵션이 있습니다.
- 그 돌연변이 서명
- 데코레이터를 사용하여 다중 정렬 | 어댑터 (상위 패턴 : 래퍼 )
나는 같은 보트에 있었고 두 번째 접근 방식을 사용하기로 결정했습니다.
private sortAddresses = (a, b) => {
let iPrimeFlag = this.sortAddressesByPrimaryFlag(a, b);
let iAlphaNum = this.sortAddressesByAlphaNum(a, b);
if (iPrimeFlag === 1) return 1;
else return iAlphaNum;
};
private sortAddressesByPrimaryFlag(a, b) {
if (b.primaryFlag > a.primaryFlag) return 1;
if (b.primaryFlag < a.primaryFlag) return -1;
return 0;
}
private sortAddressesByAlphaNum(a, b) {
let aAddress = this.$.formatAddress(a);
let bAddress = this.$.formatAddress(b);
if (aAddress > bAddress) return 1;
if (aAddress < bAddress) return -1;
return 0;
}
의지
I'm already calling this.addresses.sort(this.sortAddresses)
in several places and I'd like to keep my ChangeCost low -- especially, knowing that we may get requirements to sort on even more heuristics.
So, in order to follow The Gang of Four's Two 'Rules of Thumb' --
Program to an interface, not an implementation.
and
Encapsulate what varies.
-- I decided to keep my signature the same and wrap my original method.
It would be useful if we didn't have to go through and change each line where we invoke this.addresses.sort
. Instead, we'd like to be able to add an indefinite number of sorting "heuristics" to the action of sorting.
The goal is to prioritize address objects whose primaryFlag
is 'Y'
and then take the address string -- '0000 Some St, #0000, City, ST 00000'
-- and sort these alphanumerically. Since 'Y'
is >
'N'
, we'd like to move it up in the list, visually, by lowering its index. Sorting the address string alphanumerically says that if 'Colorado'
is >
'Alabama'
, then we should bump 'Colorado'
down in the list visually by increasing its index.
Usage
This is used for sorting Addresses by different values. One value, primaryFlag
, is to denote if its the [ only ] default address; in my case, primaryFlag
is a sting of 'Y'
or 'N'
, not a boolean (ask my Back-End teammates why in the world?). The other value, this.$.formatAddress(a|b)
, takes these address [object Object]
's -- a
and b
-- and invokes formatAddress
off of my Sandbox this.$
.
The line if (iPrimeFlag === 1) return 1;
is saying, "anytime primaryFlag is 1, just bump that toward the head (beginning) of the array, otherwise, do whatever the alphanumeric heuristic decides", which allows us to prioritize by one heuristic while falling back on another.
Also note, .bind(undefined, 'prop')
is not being used in my actual code as I don't need it; this is just here for demonstrative purposes.
Now, I know I'm that person who provided some TypeScript -- lemme know if you don't understand what's happening in this code :)
Cheers!
ReferenceURL : https://stackoverflow.com/questions/8537602/any-way-to-extend-javascripts-array-sort-method-to-accept-another-parameter
'IT TIP' 카테고리의 다른 글
주어진 열의 데이터 프레임을 집계하고 다른 열을 표시합니다. (0) | 2021.01.10 |
---|---|
Scala 리터럴 식별자 (백틱)에 대한 설명이 필요합니다. (0) | 2021.01.10 |
Postgres에서 LIKE와 ~의 차이점 (0) | 2021.01.10 |
intent.setType (type)의 가능한 인 텐트 유형은 무엇입니까? (0) | 2021.01.10 |
이미지 버튼이 프로그래밍 방식으로 변경됩니까? (0) | 2021.01.10 |