简体   繁体   English

Javascript - 通过嵌套值对JSON对象进行排序

[英]Javascript - sorting JSON object by a nested value

Summary : there is a multilevel parent-child comment system.ie 简介:有一个多层次的亲子评论系统

Example : 示例:

comment 1
    comment 1-1
        comment 1-1-1
    comment 1-2
        comment 1-2-1
             comment 1-2-2

Here, comment 1 is parent and comment 1-1 & comment 1-2 both are child of comment 1 and so on.. 这里, comment 1是父母, comment 1-1comment 1-2都是comment 1孩子,依此类推。

Requirement : 要求:

we want to achieve the sorting of whole object based on property value .ie timestamp (latest comment or reply will come on the top). 我们希望基于property value实现整个对象的sortingtimestamp (最新评论或回复将在顶部)。

JSON Object : JSON对象:

{
  "CommentText": "",
  "CommentCreateStamp": "2016-03-22",
  "Comments": [{
    "CommentText": "comment 1",
    "CommentCreateStamp": "2016-03-09",
    "Comments": [{
      "CommentText": "comment 1-1",
      "CommentCreateStamp": "2016-03-15",
      "Comments": [{
        "CommentText": "comment 1-1-1",
        "CommentCreateStamp": "2016-03-21",
        "Comments": null
      }]
    }]
  }],
  "Comments": [{
    "CommentText": "comment 2",
    "CommentCreateStamp": "2016-03-12",
    "Comments": [{
      "CommentText": "comment 2-1",
      "CommentCreateStamp": "2016-03-10",
      "Comments": [{
        "CommentText": "comment 2-1-1",
        "CommentCreateStamp": "2016-03-14",
        "Comments": null
      }]
    }]
  }]
}

i tried so far : 我到目前为止尝试过:

JSfiddle : https://jsfiddle.net/asceeevb/ JSfiddle: https ://jsfiddle.net/asceeevb/

I seen lot of questions on stackoverflow but not working as per requirement. 我在stackoverflow上看到了很多问题,但没有按照要求工作。

Any immediate help will be highly appreciable. 任何直接的帮助都将非常值得注意。 Thanks 谢谢

I am not entirely sure what you are asking, but there a couple of things that seem wrong with your code: 我不完全确定你在问什么,但是你的代码中有一些看似错误的东西:

  • you redefined the comments property of the object, perhaps you wanted an array? 你重新定义了对象的comments属性,也许你想要一个数组?
  • your sorting function is supposed to return a value based on comparison of elements, not output it. 你的排序函数应该根据元素的比较返回一个值,而不是输出它。 See this SO question for date comparison. 请参阅此SO问题以进行日期比较。

Update: You were close, what you were missing were calls to sorting for the nested comments. 更新:你很接近,你所缺少的是调用嵌套注释的sorting Here is a snippet that calls sorting recursively: 这是一个递归调用sorting的片段:

 var people = { "CommentText": "", "CommentCreateStamp": "", "Comments": [{ "CommentText": "c1", "CommentCreateStamp": "2016-03-23 06:05:36", "Comments": [{ "CommentText": "c2", "CommentCreateStamp": "2016-03-23 06:05:59", }], }, { "CommentText": "a1", "CommentCreateStamp": "2017-03-23 06:05:45", "Comments": [{ "CommentText": "a2", "CommentCreateStamp": "2016-03-23 06:06:05", }, { "CommentText": "a3", "CommentCreateStamp": "2016-03-23 06:06:16", }, { "CommentText": "a4", "CommentCreateStamp": "2016-03-23 06:06:23", }], }], }; function sorting(js_object, key_to_sort_by) { function sortByKey(a, b) { var x = a[key_to_sort_by]; var y = b[key_to_sort_by]; return ((x < y) ? 1 : ((x > y) ? -1 : 0)); }; js_object.sort(sortByKey); }; function sortComments(comments) { sorting(comments, 'CommentCreateStamp'); for (var i = 0; i < comments.length; i++) if (comments[i].hasOwnProperty('Comments')) sortComments(comments[i].Comments); }; sortComments(people.Comments); console.log(people.Comments); 

You could make a flat array which keeps the reference and sort it by CommentCreateStamp . 您可以创建一个平面数组来保留引用并通过CommentCreateStamp对其进行排序。

 function getFlat(o) { this.push(o); Array.isArray(o.Comments) && o.Comments.forEach(getFlat.bind(this)); } var object = { "CommentText": "", "CommentCreateStamp": "2016-03-22", "Comments": [{ "CommentText": "comment 1", "CommentCreateStamp": "2016-03-18", "Comments": [{ "CommentText": "comment 1-1", "CommentCreateStamp": "2016-03-15", "Comments": [{ "CommentText": "comment 1-1-1", "CommentCreateStamp": "2016-03-21", "Comments": null }] }] }] }, flat = []; getFlat.bind(flat)(object); flat.sort(function (a, b) { return a.CommentCreateStamp.localeCompare(b.CommentCreateStamp); }); document.write('<pre>' + JSON.stringify(flat, 0, 4) + '</pre>'); 

Refining the @changed answer slightly -- I find that the following works pretty well: 稍微改进@changed的答案 - 我发现以下效果非常好:

  export function sortObj(jsObj, sortKey,flgReverse) {
    sortKey = sortKey.split(".");
    let sk = '';
    Object.keys(sortKey).forEach(function(key,idx){
    sk += '[\'' + sortKey[key] + '\']';
    });
    function sortByKey(a, b) {
      var x = eval("a" + sk);
      var y = eval("b" + sk);
      if(flgReverse) return  ((x < y) ? -1 : ((x > y) ? 1 : 0));
      else return ((x < y) ? 1 : ((x > y) ? -1 : 0));
    };
    return jsObj.sort(sortByKey);
  }; 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM