使用复杂数据对JavaScript中的函数进行排序和比较

时间:2016-07-08 23:27:07

标签: javascript sorting compare

由于这个帖子How does sort function work in JavaScript, along with compare function

,我很清楚比较函数是如何工作的

但我想知道它如何用于复杂的数据,如下所示:

我们说我有以下数据。

var data = [{
  id: _A2, 
  parent: {
    parent_id: _A1 
  },
  createdOn: 1.1
},{
  id:_A4, 
  parent: null ,
  createdOn: 1.1
},{
  id: _A1, 
  parent: null ,
  createdOn: 1
},{
  id: _A3, 
  parent: {
    parent_id: _A1 
  },
  createdOn: 1.2
},{
  id: _A5, 
  parent: {
    parent_id: _A4 
  },
  createdOn: 1.2
}]

我想先按创建日期对其进行排序,然后将孩子与父母分组,这样我们就可以了:

var data = [{
  id: _A1, 
  parent: null ,
  createdOn: 1
},{
  id: _A2, 
  parent: {
    parent_id: 1 
  },
  createdOn: 1.1
},{
  id: _A3, 
  parent: {
    parent_id: 1 
  },
  createdOn: 1.2
},{
  id: _A4, 
  parent: null ,
  createdOn: 1.1
},{
  id: _A5, 
  parent: {
    parent_id: _A4 
  },
  createdOn: 1.2
}]

甚至可以使用sort函数吗?

3 个答案:

答案 0 :(得分:0)

同一篇文章的第二个答案很好地解释了比较对象数组中的特定属性:

https://stackoverflow.com/a/6568093/4809052

例如,如果要比较创建日期,则可以执行

var sortedArray = myArray.sort(function(a,b){
                                  return (a.createdOn - b.createdOn);
                              });

或者,如果您想按ID进行比较,则可以比较字符串_A1中的每个字符。

答案 1 :(得分:0)

我相信这就是你所要求的。简而言之,单独排序无法管理它。

data.sort(function(rec1, rec2) {
    return rec1.createdOn - rec2.createdOn;
});

var grouped = [];
data.forEach(function(record) {
    if (!record.parent) {
        grouped.push(record);
        data.forEach(function(child) {
            if (child.parent) {
                if (child.parent.parent_id == record.id) grouped.push(child);
            }
        });
    }
});

data = grouped;

答案 2 :(得分:0)

<强>更新 这是我带来的解决方案:

&#13;
&#13;
var data = [{
  id: '_A2',
  color: '#00ff00',
  parent: {
    parent_id: '_A1'
  },
  created: 1.1
}, {
  id: '_A4',
  color: '#bf1616',
  parent: null,
  created: 1.1
}, {
  id: '_A1',
  parent: null,
  color: '#469649',
  created: 1
}, {
  id: '_A3',
  color: '#00ff00',
  parent: {
    created: 1, 
    parent_id: '_A1'
  },
  created: 1.2
}, {
  id: '_A5',
  color: '#f62222',
  parent: {
    created: 1.1,
    parent_id: '_A4'
  },
  created: 1.2
},{
  id: '_A6',
  color: '#00ff00',
  parent: {
    created: 1, 
    parent_id: '_A1'
  },
  created: 11
},{
  id: '_A8',
  color: 'yellow',
  parent: {
    created: 0.5, 
    parent_id: '_A1'
  },
  created: 0.6
},{
  id: '_A7',
  color: '#c2c22b',
  parent: null,
  created: 0.5
}],
    ct = document.getElementById("unordered-data"),
    result = document.getElementById("result"),
    createRow = function (row) {
      var child = document.createElement('div');
      child.innerHTML = '<span class="row" style="background-color:' + row['color'] + '">' + row['id'] +  ' -- ' + row['created'] + '</span>';
      return child

    },


    compareFn = function (lhs, rhs) {
      return (lhs > rhs) ? 1 : (lhs < rhs ? -1 : 0);
    },

    compareSelfOrParentCreated = function (record1, record2) {
      var parent1 = record1.parent,
          parent2 = record2.parent;

      return compareFn(
        parent1 ? parent1.created : record1.created,
        parent2 ? parent2.created : record2.created
      );

    },
    compareSelfOrParentId = function (record1, record2) {
      var parentId1 = record1.parent,
          parentId2 = record2.parent;
      return compareFn(!!parentId1 ? parentId1.id : record1.id,
                       !!parentId2 ? parentId2.id : record2.id);
    },

    idPropertyOrEmptyString = function (obj) {
      return (!!obj && !!obj.id) ? obj.id : '';
    };

for (row in data) {
  ct.appendChild(createRow(data[row]));
}

for(r in data){
  data[r]._id =  idPropertyOrEmptyString(data[r].parent);
}

data.sort(function(r1, r2){
  var cmpCreated = compareSelfOrParentCreated(r1, r2); 
  if(cmpCreated === 0){
    var cmpParent = compareSelfOrParentId(r1, r2);
    if(cmpParent === 0){
      var parentAsc = compareFn(r1._id, r2._id);
      if(parentAsc === 0){
       return compareFn(r1.created, r2.created);
      } else{
        return parentAsc;
      }
    } else {
      return cmpParent
    }
  } else{
    return cmpCreated;
  }
});

for (row in data) {
  result.appendChild(createRow(data[row]));
}
&#13;
.row {
  display:block;
  width:200px;
  padding:10px;
}
&#13;
<h2>
 Unordered data
</h2>
<div id="unordered-data">
</div>

<h2>
Result
</h2>

<div id="result">

</div>
&#13;
&#13;
&#13;