2017-02-13 11 views
-1

私はjavascriptでソートする必要があるオブジェクトの配列を持っています(es6は問題ありません)、またはjqueryです。値はサブオブジェクトにあるため、データは通常のオブジェクト配列よりも少し複雑です。ソートするデータが動的キーのオブジェクト内にある動的キーをソートする必要があります。たとえば、 'id'を昇順または降順にソートする必要があり、データはid.dataにあります。Javascriptオブジェクトのサブキーのオブジェクトの配列を並べ替えます。

[{ 
    "_row": {}, 
    "_parent": {}, 
    "id": {"data": 112, "cell": {}}, 
    "name": {"data": "D'Amore, Volkman and Cole", "cell": {}}, 
    "check_name": {"data": "", "cell": {}}, 
    "account_number": {"data": "5534867831801846", "cell": {}}, 
    "main_email": {"data": "[email protected]", "cell": {}}, 
    "cc_email": {"data": "[email protected]", "cell": {}}, 
    "main_phone": {"data": "1-845-550-6422", "cell": {}}, 
    "work_phone": {"data": "+1 (859) 399-6372", "cell": {}}, 
    "mobile": {"data": "292-242-7626 x798", "cell": {}}, 
    "fax": {"data": "", "cell": {}}, 
    "active": {"data": 1, "cell": {}}, 
    "billing_address": {"data": "24226 Mackenzie Junctions Suite 393\nDonaldside, GA 87531", "cell": {}}, 
    "shipping_address": {"data": "478 Toy Loaf Suite 552\nWaelchiberg, ND 70701-3633", "cell": {}}, 
    "comments": {"data": "", "cell": {}} 
}, { 
    "_row": {}, 
    "_parent": {}, 
    "id": {"data": 120, "cell": {}}, 
    "name": {"data": "Carroll, Rice and Reilly", "cell": {}}, 
    "check_name": {"data": "", "cell": {}}, 
    "account_number": {"data": "4539358256447", "cell": {}}, 
    "main_email": {"data": "[email protected]", "cell": {}}, 
    "cc_email": {"data": "[email protected]", "cell": {}}, 
    "main_phone": {"data": "612-864-9512", "cell": {}}, 
    "work_phone": {"data": "(519) 761-1805", "cell": {}}, 
    "mobile": {"data": "+1-730-669-4339", "cell": {}}, 
    "fax": {"data": "", "cell": {}}, 
    "active": {"data": 1, "cell": {}}, 
    "billing_address": {"data": "848 Rashawn Causeway\nHauckberg, GA 21193", "cell": {}}, 
    "shipping_address": {"data": "3458 Wolff Cape Suite 336\nWolfmouth, DC 35821", "cell": {}}, 
    "comments": {"data": "", "cell": {}} 
}, { 
    "_row": {}, 
    "_parent": {}, 
    "id": {"data": 122, "cell": {}}, 
    "name": {"data": "Denesik and Sons", "cell": {}}, 
    "check_name": {"data": "", "cell": {}}, 
    "account_number": {"data": "6011079688853496", "cell": {}}, 
    "main_email": {"data": "[email protected]", "cell": {}}, 
    "cc_email": {"data": "[email protected]", "cell": {}}, 
    "main_phone": {"data": "569-382-2580 x1764", "cell": {}}, 
    "work_phone": {"data": "705.782.2219", "cell": {}}, 
    "mobile": {"data": "936-586-1978", "cell": {}}, 
    "fax": {"data": "", "cell": {}}, 
    "active": {"data": 1, "cell": {}}, 
    "billing_address": {"data": "1864 Donnelly Parkway Suite 222\nPort Hailieburgh, NC 08808-0938", "cell": {}}, 
    "shipping_address": {"data": "28476 Jerald Valleys Apt. 537\nNorth Vancemouth, DC 16865-0793", "cell": {}}, 
    "comments": {"data": "", "cell": {}} 
}, { 
    "_row": {}, 
    "_parent": {}, 
    "id": {"data": 124, "cell": {}}, 
    "name": {"data": "Trantow, Botsford and Runolfsson", "cell": {}}, 
    "check_name": {"data": "", "cell": {}}, 
    "account_number": {"data": "4556163511909216", "cell": {}}, 
    "main_email": {"data": "[email protected]", "cell": {}}, 
    "cc_email": {"data": "[email protected]", "cell": {}}, 
    "main_phone": {"data": "+16989316200", "cell": {}}, 
    "work_phone": {"data": "969.610.8041 x8593", "cell": {}}, 
    "mobile": {"data": "680.717.5368", "cell": {}}, 
    "fax": {"data": "", "cell": {}}, 
    "active": {"data": 1, "cell": {}}, 
    "billing_address": {"data": "96778 VonRueden Square Suite 421\nKennafort, SC 70938", "cell": {}}, 
    "shipping_address": {"data": "13334 Orion Green\nEast Lillieborough, ND 19714", "cell": {}}, 
    "comments": {"data": "", "cell": {}} 
}] 

合併症の次のステップは、私は、その後、別のキーは、アクティブなように、名前のidでソートしたいことなど

任意のアイデアですか? .sortを繋ぐことはできますか? (セルオブジェクトを使用していないように見えますが、私はそれを削除して人生を楽にすることができます)。最初のソートは正常に動作し、複数の列を並べ替えることは機能していないようです。

試み1:dynamicSortはかなりクールでthenByを使用して、スタックオーバーフローSort array of objects by string property value in JavaScript

dynamicSort(property) { 
    let sortOrder = 1; 
    if (property[0] === "-") { 
     sortOrder = -1; 
     property = property.substr(1); 
    } 
    return function (a, b) { 
     let result = (a[property].data < b[property].data) ? -1 : (a[property].data > b[property].data) ? 1 : 0; 
     return result * sortOrder; 
    } 
} 

試み2から引き出された

 //sort_array looks like [{db_field:'asc'},etc...] 
    //we need to sort row based on data for this.tdo[row][db_filed]['data'] 
    this.tdo.sort((a,b) => { 
     sort_array.forEach(sort => { 
      let keys = Object.keys(sort); 
      let name = keys[0]; 
      if(sort[keys[0]] =='asc') 
      { 
       this.tdo = this.tdo.sort(this.dynamicSort(name)); 
      } 
      else 
      { 
       this.tdo = this.tdo.sort(this.dynamicSort('-'+name)); 
      } 
     }) 

    }) 

。私はその閉鎖問題でソートスタックする方法の例を見つけました:

let sort_stack = firstBy(function (v1, v2) { return 0 }); 
    sort_array.forEach(sort => { 
     let keys = Object.keys(sort); 
     let name = keys[0]; 
     if(sort[keys[0]] =='asc') 
     { 
      sort_stack = sort_stack.thenBy(function (v1) { return v1[name].data; }); 
     } 
     else 
     { 
      sort_stack = sort_stack.thenBy(function (v1) { return v1[name].data ; },-1); 
     } 
    }) 

    this.tdo.sort(sort_stack); 

また、私はデータの種類に基づいて、ユーザの入力サブ並べ替えを制限する必要があるかもしれません... idのような列がしますソート一度だけ

として

ない私がダウン票を得た理由は、この種はかなり複雑であり、あなたがカスタム比較関数を使用してアレイ上)(連鎖の並べ替えを使用することができます.sortドキュメント

+0

はい、あなたは[ '.sort'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/使用することができますソート)。あなたが記述したものとまったく同じ比較関数を書くだけです。 – Hamms

+0

それについては何が複雑ですか? 'a.id'と' b.id'を比較するのではなく、 'a.id.data'と' b.id.data'を比較します。 –

+0

http://www.javascriptkit.com/javatutors/arraysort2.shtml – CodingYoshi

答えて

0

の範囲を超えて確認してください。配列は "項目" と命名されている場合たとえば、あなたは、以下の基本コードを使用することができます。

function compare(value1, value2){ 
    if(value1 < value2) return -1; 
    else if(value1 == value2) return 0; 
    else return 1; 
} 

items = items.sort(function(item1, item2){ // First sorting criteria, e.g. by id.data 
    return compare(item1.id.data, item2.id.data); 
}).sort(function(item1, item2){ // Second sorting criteria, e.g. by active.data 
    return compare(item1.active.data, item2.active.data); 
}).sort(function(item1, item2){ // Third sorting criteria, e.g. by name.data 
    return compare(item1.name.data, item2.name.data); 
}); 

UPDATED ANSWER:

OK、それは私が、私の悪いあなたを誤解しそうです。ここでは、項目を1つのフィールドで並べ替え、次にソートされた項目を別の列で並べ替えるが、以前の並べ替えをデータベースのようなやり方で保持したいと思う。

これを行うには、ソートされたアイテムをサブアレイにグループ化し、次に2番目の条件でソートする必要があります。私はあなたのためのフィドル作成しました:

https://jsfiddle.net/d8vzn9b0/1/

をそして、ここではこれを実現するために使われているメインのコードです:私はあなたがソートを分割できるようにsplitItemsByFieldValue()機能を作成し

function compare(value1, value2){ 
    if(value1 < value2) return -1; 
    else if(value1 == value2) return 0; 
    else return 1; 
} 

function splitItemsByFieldValue(items, field){ 
    var splittedByValue = {}; 
    var key; 

    // Group items in an object-based hash indexed by the field value 
    for(var item of items){ 
    // We use a string prefix to make all object keys strings to prevent the "empty slots" in Javascript object or array based hashes 
    key = 'value_' + item[field].data; 
     if(!splittedByValue[key]) splittedByValue[key] = []; 
    splittedByValue[key].push(item); 
    } 

    // Convert the indexed array (grouped items) to a flat array (not associative) of the grouped items as subarrays 
    var splittedFlat = [], subarray; 

    for(key in splittedByValue){ 
    subarray = splittedByValue[key]; 
    splittedFlat.push(subarray); 
    } 

    return splittedFlat; 
} 

var sortedItems = []; 

var sortedByActive = items.sort(function(item1, item2){ // First sorting criteria, e.g. by active.data 
    return compare(item1.active.data, item2.active.data); 
}); 

for(var subarray of splitItemsByFieldValue(sortedByActive, 'active')){ 
    var sortedSubArray = subarray.sort(function(item1, item2){ // Second sorting criteria, e.g. by name.data 
    return (item1.name && (typeof item1.name.data) == 'string') ? item1.name.data.localeCompare(item2.name.data) : 1; 
    }); 

    for(var item of sortedSubArray){ 
    sortedItems.push(item); 
    } 
} 

注意アイテムを特定のフィールドでサブアレイに変換します。このコードを基に、より多くのソート基準を追加することができます。また、localeCompare()を使って名前をソートするので、ナショナルソート(数値ではなくテキスト)の比較が使用され、アクティブなような他のフィールドには標準的な数値比較が使用されます。

ところで、IDは常に一意である必要があるため、「ID」でソートする必要はありません。 2つのソーティング基準を同時に指定することはできません。これは、不連続な値を持つことができます。それ以外の場合は、最初に適用される基準と無視されます。たとえば、最初にIDで並べ替えると、結果がまだIDでソートされるため、アクティブで並べ替える必要はなく、フィールドで並べ替える必要はありません。

並べ替えを使用するときは、まず離散値の有限リストを持つ列をソートし、その後に連続(たとえば、価格、量など)または不定の離散値(例えば一意のID)。

+0

ありがとう、私はこれを1つの動的ソートフィールドで動作させています。私は並べ替えを動的に連鎖させる方法を困惑しています.... – Iannazzi

+0

私の更新された答えを確認してください。 – ablopez

+0

おかげで再び....私も、私は応答に基づいてしまった場所を示すために質問を更新しました。あなたの更新に基づいて、私は他の種類を殺すのIDをクリックすると同じように、ソートに優れたデータセットと制限が必要だと思います。私はそれが完了したときに私はこれに戻ってきます! – Iannazzi

0

var arr = [{"_row":{},"_parent":{},"id":{"data":112,"cell":{}},"rest": "abcd"},{"_row":{},"_parent":{},"id":{"data":120,"cell":{}},"rest": "rthu"},{"_row":{},"_parent":{},"id":{"data":122,"cell":{}},"rest": "just an example"},{"_row":{},"_parent":{},"id":{"data":124,"cell":{}},"rest": "efgh"}]; 
 

 
arr.sort((a, b) => a.id.data - b.id.data || a.rest.localCompare(b.rest) /* || another comparison ...*/); // switch a and b to swith the order 
 

 
console.log(arr);

関連する問題