속성 값을 기준으로 개체 정렬


88

Javascript 만 사용하여 다음 시나리오를 구현하는 방법 :

  • 자동차 만들기속성 (최고 속도, 브랜드 등)이 개체
  • 해당 속성별로 정렬 된 자동차 목록 정렬

3
@durilai : 자바 스크립트가 되는 객체 지향 자바 스크립트의 OO 모델을 기반으로 프로토 타이핑 하고 정말, 정말 다양한 ... en.wikipedia.org/wiki/Prototype-based_programming
기독교 C. Salvadó

내가 사용 lodash.js 추천 : lodash.com/docs#sortBy
화학 프로그래머

답변:


159

자바 스크립트에는 다른 함수를 매개 변수로 사용할 수 있는 정렬 함수가 있습니다. 두 번째 함수는 두 요소를 비교하는 데 사용됩니다.

예:

cars = [

    {
        name: "Honda",
        speed: 80
    },

    {
        name: "BMW",
        speed: 180
    },

    {
        name: "Trabi",
        speed: 40
    },

    {
        name: "Ferrari",
        speed: 200
    }
]


cars.sort(function(a, b) { 
    return a.speed - b.speed;
})

for(var i in cars)
    document.writeln(cars[i].name) // Trabi Honda BMW Ferrari 

좋아요, 귀하의 의견에서 '정렬'이라는 단어를 잘못된 의미로 사용하고 있음을 알았습니다. 프로그래밍에서 "정렬"은 "일을 그룹으로 정렬"이 아니라 "특정 순서로 물건을 배치"를 의미합니다. 후자는 훨씬 더 간단합니다. 이것은 실제 세계에서 사물을 "정렬"하는 방법입니다.

  • 두 개의 빈 배열 ( "상자") 만들기
  • 목록의 각 개체에 대해 기준과 일치하는지 확인하십시오.
  • 그렇다면 첫 번째 "상자"에 넣으십시오.
  • 아니라면 두 번째 "상자"에 넣으십시오.

10
편의를위한 간단한 참고 :이 ( a.someProp - b.someProp)는 가장 낮은 것에서 가장 높은 것 순으로 정렬 하고, 반대 ( b.someProp - a.someProp)는 가장 높은 것에서 가장 낮은 것 순으로 정렬합니다. 기본적으로 함수가 0 미만을 반환하면 a가 b 앞에옵니다.
user56reinstatemonica8

또한이 솔루션은 정렬하는 속성이 숫자 인 경우에만 작동합니다. 이것은 최고 속도로 정렬하는 예제에서 작동하지만 자동차 브랜드별로 정렬하려는 경우이 솔루션은 문자열을 알파벳순으로 정렬하지 않습니다. Cheeso는 숫자와 문자열을 기준으로 정렬 할 수있는 답을 제공합니다.
Cole Marshall

23

예.

이것은 Windows의 cscript.exe에서 실행됩니다.

// define the Car class
(function() {
    // makeClass - By John Resig (MIT Licensed)
    // Allows either new User() or User() to be employed for construction.
    function makeClass(){
        return function(args){
            if ( this instanceof arguments.callee ) {
                if ( typeof this.init == "function" )
                    this.init.apply( this, (args && args.callee) ? args : arguments );
            } else
                return new arguments.callee( arguments );
        };
    }

    Car = makeClass();

    Car.prototype.init = function(make, model, price, topSpeed, weight) {
        this.make = make;
        this.model = model;
        this.price = price;
        this.weight = weight;
        this.topSpeed = topSpeed;
    };
})();


// create a list of cars
var autos = [
    new Car("Chevy", "Corvair", 1800, 88, 2900),
    new Car("Buick", "LeSabre", 31000, 138, 3700),
    new Car("Toyota", "Prius", 24000, 103, 3200),
    new Car("Porsche", "911", 92000, 155, 3100),
    new Car("Mercedes", "E500", 67000, 145, 3800),
    new Car("VW", "Passat", 31000, 135, 3700)
];

// a list of sorting functions
var sorters = {
    byWeight : function(a,b) {
        return (a.weight - b.weight);
    },
    bySpeed : function(a,b) {
        return (a.topSpeed - b.topSpeed);
    },
    byPrice : function(a,b) {
        return (a.price - b.price);
    },
    byModelName : function(a,b) {
        return ((a.model < b.model) ? -1 : ((a.model > b.model) ? 1 : 0));
    },
    byMake : function(a,b) {
        return ((a.make < b.make) ? -1 : ((a.make > b.make) ? 1 : 0));
    }
};

function say(s) {WScript.Echo(s);}

function show(title)
{
    say ("sorted by: "+title);
    for (var i=0; i < autos.length; i++) {
        say("  " + autos[i].model);
    }
    say(" ");
}

autos.sort(sorters.byWeight);
show("Weight");

autos.sort(sorters.byModelName);
show("Name");

autos.sort(sorters.byPrice);
show("Price");

일반 분류기를 만들 수도 있습니다.

var byProperty = function(prop) {
    return function(a,b) {
        if (typeof a[prop] == "number") {
            return (a[prop] - b[prop]);
        } else {
            return ((a[prop] < b[prop]) ? -1 : ((a[prop] > b[prop]) ? 1 : 0));
        }
    };
};

autos.sort(byProperty("topSpeed"));
show("Top Speed");

13

이 간단한 함수를 직접 작성했습니다.

function sortObj(list, key) {
    function compare(a, b) {
        a = a[key];
        b = b[key];
        var type = (typeof(a) === 'string' ||
                    typeof(b) === 'string') ? 'string' : 'number';
        var result;
        if (type === 'string') result = a.localeCompare(b);
        else result = a - b;
        return result;
    }
    return list.sort(compare);
}

예를 들어 자동차 목록이 있습니다.

var cars= [{brand: 'audi', speed: 240}, {brand: 'fiat', speed: 190}];
var carsSortedByBrand = sortObj(cars, 'brand');
var carsSortedBySpeed = sortObj(cars, 'speed');

6

특정 속성을 기준으로 객체 목록을 오름차순으로 정렬해야한다고 가정 해 보겠습니다.이 예제에서는 "name"속성을 기준으로 정렬해야한다고 가정 해 보겠습니다. 다음은 필수 코드입니다.

var list_Objects = [{"name"="Bob"},{"name"="Jay"},{"name"="Abhi"}];
Console.log(list_Objects);   //[{"name"="Bob"},{"name"="Jay"},{"name"="Abhi"}]
    list_Objects.sort(function(a,b){
        return a["name"].localeCompare(b["name"]); 
    });
Console.log(list_Objects);  //[{"name"="Abhi"},{"name"="Bob"},{"name"="Jay"}]

1
오타가있는 것 같아요? return a [ "name"]. localeCompare (b. [ "name"]); 반환해야합니다. a [ "name"]. localeCompare (b [ "name"]); (b 이후. 제거)
Little Brain

3

함께 ES6 화살표 기능 은 다음과 같이 될 것입니다 :

//Let's say we have these cars
let cars = [ { brand: 'Porsche', top_speed: 260 },
  { brand: 'Benz', top_speed: 110 },
  { brand: 'Fiat', top_speed: 90 },
  { brand: 'Aston Martin', top_speed: 70 } ]

Array.prototype.sort() 비교기 함수를 받아 들일 수 있습니다 (여기서는 화살표 표기법을 사용했지만 일반 함수는 동일하게 작동합니다).

let sortedByBrand = [...cars].sort((first, second) => first.brand > second.brand)

// [ { brand: 'Aston Martin', top_speed: 70 },
//   { brand: 'Benz', top_speed: 110 },
//   { brand: 'Fiat', top_speed: 90 },
//   { brand: 'Porsche', top_speed: 260 } ]

위의 접근 방식은 cars 배열의 내용을 새 배열로 복사하고 브랜드 이름을 기준으로 알파벳순으로 정렬합니다. 마찬가지로 다른 함수를 전달할 수 있습니다.

let sortedBySpeed =[...cars].sort((first, second) => first.top_speed > second.top_speed)

//[ { brand: 'Aston Martin', top_speed: 70 },
//  { brand: 'Fiat', top_speed: 90 },
//  { brand: 'Benz', top_speed: 110 },
//  { brand: 'Porsche', top_speed: 260 } ]

원래 배열 cars.sort(comparatorFunction)을 변경해도 상관 없습니다 .


3

다음은 객체를 생성 및 배열하고 숫자 또는 알파벳순으로 정렬하는 간단한 예입니다.

// Create Objects Array

var arrayCarObjects = [
{brand: "Honda",        topSpeed: 45},
{brand: "Ford",         topSpeed: 6},
{brand: "Toyota",       topSpeed: 240},
{brand: "Chevrolet",    topSpeed: 120},
{brand: "Ferrari",      topSpeed: 1000}
];

// Sort Objects Numerically

arrayCarObjects.sort((a, b) => (a.topSpeed - b.topSpeed));

// Sort Objects Alphabetically

arrayCarObjects.sort((a, b) => (a.brand > b.brand) ? 1 : -1);

2

역 분류 방식의 Cheeso 솔루션 버전으로, 명확하지 않기 위해 삼항 표현도 제거했습니다 (그러나 이것은 개인적인 취향입니다).

function(prop, reverse) {
  return function(a, b) {
    if (typeof a[prop] === 'number') {
      return (a[prop] - b[prop]);
    }

    if (a[prop] < b[prop]) {
      return reverse ? 1 : -1;
    }

    if (a[prop] > b[prop]) {
      return reverse ? -1 : 1;
    }

    return 0;
  };
};

1
완전히 반대되는 번호는 필요return !!reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
마크 Schultheiss

예, 이제 숫자에 대한 역 확인이 없으므로 고맙습니다. 수정해야합니다. 이중하지만 왜 !이 괜찮 너무 :return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
MARC를

1
!!자바 스크립트 값의 "falsy"자연에 반대 네이티브 부울 형의 값에 힘 유형 강제 변환이 엄격하게 필요하지만 관계를 설명 목적 적어도 나에게 없다. 참고로 당신은 값을 반환 할 때 !!는 말을하는 것입니다 "falsy"값이 기본 유형과 반대로 기본 부울 유형 typeof !!undefined또는 typeof !!null등 반환 "부울"주 !!" "입니다 true!!""입니다 false(공간의에서 어떤 공간 문자열)하지만 이미 알고있을 것입니다.
마크 Schultheiss
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.