プロパティ値によるオブジェクトの並べ替え


88

Javascriptのみを使用して次のシナリオを実装する方法:

  • プロパティ(最高速度、ブランドなど)を使用して車のオブジェクトを作成します
  • それらのプロパティで注文された車のリストを並べ替えます

3
@durilai:JavaScriptがあるオブジェクト指向は、JavaScriptのオブジェクト指向モデルが基づいているプロトタイピングと本当に、本当に万能... en.wikipedia.org/wiki/Prototype-based_programming
クリスチャンC.Salvadó

lodash.jsの使用をお勧めします:lodash.com/docs#sortBy
ケミカルプログラマー

回答:


159

javascriptには種類があります別の関数をパラメーターとして受け取ることができる関数があります。その2番目の関数は、2つの要素を比較するために使用されます。

例:

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 

わかりました、あなたのコメントから、あなたが間違った意味で「ソート」という言葉を使用していることがわかります。プログラミングにおいて、「ソート」とは「物事をグループに並べる」ではなく、「物事を特定の順序に並べる」ことを意味します。後者ははるかに単純です-これはあなたが現実の世界で物事を「分類」する方法です

  • 2つの空の配列(「ボックス」)を作成します
  • リスト内の各オブジェクトについて、基準に一致するかどうかを確認します
  • はいの場合は、最初の「ボックス」に入れます
  • いいえの場合は、2番目の「ボックス」に入れます

10
便宜上の簡単な注意:this(a.someProp - b.someProp)は最低から最高b.someProp - a.somePropソートし、逆()は最高から最低にソートします。基本的に、関数が0未満を返す場合、aはbの前に来ます。
user56reinstatemonica8 2013

また、このソリューションは、並べ替えるプロパティが数値の場合にのみ機能することにも注意してください。これは、最高速度で並べ替える例では機能しますが、車のブランドで並べ替える場合、このソリューションでは文字列をアルファベット順に並べ替えることはできません。Cheesoは、数字と文字列の両方で並べ替えるための答えを提供します。
コールマーシャル

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の後の。を削除)
リトルブレイン

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 } ]

上記のアプローチでは、車の配列の内容を新しいものにコピーし、ブランド名に基づいてアルファベット順に並べ替えます。同様に、別の関数を渡すことができます。

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ソリューションのバージョンで、明確さが不足しているために3値式も削除しました(ただし、これは個人的な好みです)。

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]);
Mark Schultheiss

はい、現在は番号の逆チェックがないので、ありがとうございます。修正する必要があります。しかし、なぜ!これが2倍でも問題ないのか:return reverse ? (a[prop] - b[prop]) * -1 : (a[prop] - b[prop]);
Marcs 2017年

1
!!力型強制ネイティブのブール型の値には、JavaScript値の「falsy」自然に反対厳密には必要ありませんが、少なくとも私には明確化を目的として。なお、であなたが値を返すとき!!、それは言うことです「falsy」値でネイティブ型とは対照的に、ネイティブブール種類であるtypeof !!undefinedtypeof !!nullなどの戻り「ブール」注!!" "であるtrueが、!!""であるfalse(スペース、中にスペースは文字列)しかし、あなたはおそらくそれをすでに知っていたでしょう。
Mark Schultheiss 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.