2017-02-13 161 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吗? (这看起来像我不使用细胞对象,也许我可以删除它,使我的生活更轻松,我想我在几年前添加了一个非常重要的原因)

这里是我所想的out ..第一种排序工作正常,排序多个列似乎没有工作。

尝试1:

 //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)); 
      } 
     }) 

    }) 

其中dynamicSort从堆栈溢出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拉动,使用thenBy这是相当凉爽。我发现了一个例子,如何堆叠在其关闭的问题排序:

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); 
}); 

修订答:

OK,看来我误会你了,是我不好。我现在看到您想要按一个字段对项目进行排序,然后按照类似数据库的方式,通过单独的列保留先前排序的项目。

为此,您需要将已排序的项目分组到子数组中,然后根据第二个条件逐个对它们进行排序。我创建了一个捣鼓你:

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

谢谢,我有一个动态排序字段的工作。我很难将动态链接在一起...... – 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);