根据值重新排列JSON的一部分

时间:2015-09-04 19:40:00

标签: javascript json

我有以下JSON,我想根据' rank'重新安排。如果类型是'水果'或者'肉类。并按照它出现的顺序保留JSON的其余部分。类型'水果'和'肉类'将有排名,但类型&蔬菜'和日记'在某些情况下,排名不是强制性的。

原始值:

var results = {"docs":[
  {"type":"fruit","name":"apple","rank": 10}, 
  {"type":"vegetable","name":"carrot","rank": 0}, 
  {"type":"fruit","name":"grape","rank": 9}, 
  {"type":"meat","name":"beef","rank": 9}, 
  {"type":"meat","name":"fish","rank": 10.1}, 
  {"type":"vegetable","name":"tamato"}, 
  {"type":"meat","name":"chicken","rank": 10}, 
  {"type":"diary","name":"eggs"}, 
  {"type":"vegetable","name":"peas","rank": 0}, 
  {"type":"fruit","name":"orange","rank": 9.1}, 
  {"type":"diary","name":"milk","rank": 10},
  {"type":"fruit","name":"banana","rank": 9.8}
]};

预期价值:

var results = {"docs":[
  {"type":"fruit","name":"apple","rank": 10}, 
  {"type":"fruit","name":"banana","rank": 9.8},
  {"type":"fruit","name":"orange","rank": 9.1}, 
  {"type":"fruit","name":"grape","rank": 9}, 
  {"type":"meat","name":"fish","rank": 10.1}, 
  {"type":"meat","name":"chicken","rank": 10}, 
  {"type":"meat","name":"beef","rank": 9}, 
  {"type":"vegetable","name":"carrot","rank": 0}, 
  {"type":"vegetable","name":"tamato"}, 
  {"type":"diary","name":"eggs"}, 
  {"type":"vegetable","name":"peas","rank": 0}, 
  {"type":"diary","name":"milk","rank": 10}
]};

提前致谢。感谢帮助。

1 个答案:

答案 0 :(得分:1)

JSON对象的docs元素是一个JSON对象数组,因此您可以使用Array.sort()方法对JSON对象进行排序(请参阅:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)。诀窍是编写一个排序函数,按照您希望它们排序的方式对JSON对象进行排序。

我把它分解为两个函数,一个按类型排序,另一个按排序排序。

按类型分类时,我们希望水果的分类指数低于肉类,而乳制品和蔬菜的分类指数低于水果或肉类。我们可以在compareType中使用types数组的索引来帮助我们按类型排序。 “fruit”的索引大于“meat”的索引,并且不在数组中的任何内容的索引(“dairy”和“vegetable”)是-1。 types数组中的较低索引对应于最终排序数组中的较高索引。所以如果a.type< b.type,我们返回1.

按排名排序时,应将较高排名排序为较低的排名。最终排序函数首先比较对象的类型,如果类型相等,则比较它们的排名。

var results = {"docs":[
  {"type":"fruit","name":"apple","rank": 10}, 
  {"type":"vegetable","name":"carrot","rank": 0}, 
  {"type":"fruit","name":"grape","rank": 9}, 
  {"type":"meat","name":"beef","rank": 9}, 
  {"type":"meat","name":"fish","rank": 10.1}, 
  {"type":"vegetable","name":"tamato"}, 
  {"type":"meat","name":"chicken","rank": 10}, 
  {"type":"diary","name":"eggs"}, 
  {"type":"vegetable","name":"peas","rank": 0}, 
  {"type":"fruit","name":"orange","rank": 9.1}, 
  {"type":"diary","name":"milk","rank": 10},
  {"type":"fruit","name":"banana","rank": 9.8}
]};

function compareRank(a, b) {
  if(a.rank < b.rank) {
    return 1;
  }
  else if(a.rank > b.rank) {
    return -1;
  }
  else {
    return 0;
  }
}

function compareType(a, b) {
  var types = ["meat", "fruit"];

  if(a.type === b.type) {
    return 0;
  }
  else if(types.indexOf(a.type) < types.indexOf(b.type)) {
    return 1;
  }
  else {
    return -1;
  }
}

var docs = results.docs;
docs.sort(function(a, b) {
  if(compareType(a, b) === 0) {
    return compareRank(a, b);
  }
  else {
    return compareType(a, b);
  }
});