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

时间:2016-03-22 16:49:40

标签: javascript jquery json sorting

摘要:有一个多层次的父子评论系统.i.e。

示例:

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

此处, comment 1 是父级, comment 1-1 & comment 1-2 都是 comment 1 的孩子等等。

要求:

我们希望基于sorting实现整个对象的property valuetimestamp(最新评论或回复将在最上方)。

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

我到目前为止尝试过:

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

我在stackoverflow上看到了很多问题,但没有按照要求工作。

任何直接的帮助都会非常值得注意。感谢

3 个答案:

答案 0 :(得分:2)

我不完全确定你在问什么,但是有些事情似乎与你的代码有关:

  • 你重新定义了对象的comments属性,也许你想要一个数组?
  • 你的排序函数应该根据元素的比较返回一个值,而不是输出它。有关日期比较,请参阅this SO question

更新:你很接近,你所缺少的是对sorting的嵌套评论的调用。 这是一个以递归方式调用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);

答案 1 :(得分:1)

您可以制作一个平面数组,用于保留引用并按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>');对其进行排序。

&#13;
&#13;
(i, j, k, ...)
&#13;
&#13;
&#13;

答案 2 :(得分:0)

稍微改进@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);
  };