web-dev-qa-db-ja.com

lodash /アンダースコアを使用して複数のネストされたフィールドでソートするにはどうすればよいですか?

私はこのようなことをしたい:

var data = [
    {
        sortData: {a: 'a', b: 2}
    },
    {
        sortData: {a: 'a', b: 1}
    },
    {
        sortData: {a: 'b', b: 5}
    },
    {
        sortData: {a: 'a', b: 3}
    }
];

data = _.sortBy(data, ["sortData.a", "sortData.b"]);

_.map(data, function(element) {console.log(element.sortData.a + " " + element.sortData.b);});

そして、これを出力します:

"a 1"
"a 2"
"a 3"
"b 5"

残念ながら、これは機能せず、配列は元の形式でソートされたままです。 フィールドがsortData内にネストされていない場合に機能します lodash /アンダースコアを使用して、複数のネストされたフィールドでオブジェクトの配列をソートするにはどうすればよいですか?

これをlodash機能リクエストに変更しました: https://github.com/lodash/lodash/issues/581

28
Daniel Kaplan

_.sortByAll lodashバージョン3のメソッド:

https://github.com/lodash/lodash/blob/3.10.1/doc/README.md#_sortbyallcollection-iteratees

Lodashバージョン4、統合されました:

https://lodash.com/docs#sortBy

他のオプションは、自分で値をソートすることです。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

function compareValues(v1, v2) {
    return (v1 > v2) 
        ? 1 
        : (v1 < v2 ? -1 : 0);
};


var data = [
    { a: 2, b: 1 },
    { a: 2, b: 2 },
    { a: 1, b: 3 }
];

data.sort(function (x, y) {
    var result = compareValues(x.a, y.a);

    return result === 0 
        ? compareValues(x.b, y.b) 
        : result;
});

// data after sort:
// [
//     { a: 1, b: 3 },
//     { a: 2, b: 1 },
//     { a: 2, b: 2 }
// ];
18
Tomas Kirda

更新:以下のコメントを参照してください。ほとんどの場合、これは良い解決策ではありません。


誰かが親切に答えました 私が作成した問題で 。彼の答えは次のとおりです。

_.sortBy(data, function(item) {
   return [item.sortData.a, item.sortData.b];
});

その関数から配列をreturnすることが許可されていることを知りませんでした。ドキュメントではそれについて言及していません。

37
Daniel Kaplan

並べ替え方向を指定する必要がある場合は、_.orderByLodash 4.xの関数の構文で使用できます。

_.orderBy(data, [
  function (item) { return item.sortData.a; },
  function (item) { return item.sortData.b; }
], ["asc", "desc"]);

これは最初にプロパティaで昇順で並べ替えられ、プロパティaに同じ値を持つオブジェクトの場合、プロパティbで降順に並べ替えられます。

aプロパティとbプロパティのタイプが異なる場合、期待どおりに機能します。

この構文を使用した jsbinの例 を次に示します。

19
kenjiru

驚くほど簡単な方法は次のとおりです。

_.sortBy(data, [function(item) {
    return item.sortData.a;
}, function(item) {
    return item.sortData.b;
}]);

私はlodashのソースコードをチェックすることからそれを見つけました、それは常に1つずつ機能をチェックします。

お役に立てば幸いです。

12
KimKha

ES6の簡単な構文とlodashを使用

sortBy(item.sortData, (item) => (-item.a), (item) => (-item.b))
8
Cem Arguvanlı

問題が整数が文字列に変換される場合は、整数の前にゼロを追加して、コレクションの最長と同じ長さにします。

var maxLength = _.reduce(data, function(result, item) {
    var bString = _.toString(item.sortData.b);
    return result > bString.length ? result : bString.length;            
}, 0);

_.sortBy(data, function(item) {
    var bString = _.toString(item.sortData.b);
    if(maxLength > bString.length) {
        bString = [new Array(maxLength - bString.length + 1).join('0'), bString].join('');
    }

    return [item.sortData.a, bString];
});
0
user1912899

私はこれがアンダースコアでほとんどの場合うまくいくと思う:

var properties = ["sortData.a", "sortData.b"];
data = _.sortBy(data, function (d) {
    var predicate = '';
    for (var i = 0; i < properties.length; i++)
    {
        predicate += (i == properties.length - 1 
                           ? 'd.' + properties[i]
                           : 'd.' + properties[i] + ' + ')
    }
    return eval(predicate)
});

動作し、Plunkerで確認できます

0
David Martin