如何根据对象数组中的折叠值最有效地生成数组?

时间:2013-07-06 20:30:22

标签: javascript

假设您有listA,以及已定义的“列”数组:

var listA = [{
    name: "Mike",
    exercisedateandtime: 1299233593000,
    exercise: "Jumping Jacks",
    numsets: 5
}, {
    name: "Charles",
    exercisedateandtime: 1299233593000,
    exercise: "Swimming",
    numsets: 2
}, {
    name: "Charles",
    exercisedateandtime: 1299233593000,
    exercise: "Swimming",
    numsets: 6
}, {
    name: "Mike",
    exercisedateandtime: 1299237012000,
    exercise: "Running",
    numsets: 5
}, {
    name: "William",
    exercisedateandtime: 1299237320000,
    exercise: "Fishing",
    numsets: 2
}, {
    name: "William",
    exercisedateandtime: 1299237611000,
    exercise: "Motor Boating",
    numsets: 6
}, {
    name: "Charles",
    exercisedateandtime: 1299237611000,
    exercise: "Swimming",
    numsets: 4
}];

var columns = ["Exercise Date", "Mike", "Charles", "William"]

目标是从列表A生成单个数组,以便任何恰好匹配的时间都将“折叠”。在这种情况下,输出应为:

var output = [[1299233593000, 5, 2, null]
[1299237012000, 6, null, null]
[1299237012000, 6, null, 0]
[1299237320000, null, null, 2]
[1299237320000, null, null, 2]
[1299237611000, null, 4, 6]]

请注意,当一个或多个人同时拥有“1299233593000”时,“输出”会对其进行说明并将其“折叠”为单个数组。空值显示为exercisedatetimes,其中个人没有任何“numsets”。非空值是个人在那段时间内具有“numsets”的值。

使用JavaScript进行“输出”的最佳方法是什么,同时允许变量名称(例如Fred将其信息输入listA)和变量列(假设您可以从“columns”数组中删除“William”和它不会出现在输出中。)

理想的解决方案是在速度和处理方面的最佳性能。

1 个答案:

答案 0 :(得分:1)

修改:

抱歉,误读了你的问题。这并没有真正做你想要的 - 它没有考虑到名称。但我仍然不完全清楚问题究竟是什么。

这种问题的诀窍通常是保存到目前为止收集的信息的地图(或嵌套地图),并根据需要进行更新。映射键通常应该是您需要合并的信息,因此查找是有效的。

我还没有测试过代码,它只是将对象折叠成行。根据您的问题确实存在,它可能是也可能不是一个合理的起点。

代码将标签放入结果的第0行,但是应该很容易添加对预定义列表的支持作为起点......

function collapse (array) {
  var labels = [];
  var result = [labels];
  var labelMap = 0;
  var timeMap = {};
  for (var i = 0; i < array.length; i++) {
    var row = [];
    var entry = array[i];
    var time = entry.exercisedateandtime;
    var row = timeMap[time];
    if (row == null) {
      row = [];
      timeMap[time] = row;
      result.push(row);
    }
    for (var key in entry) {
      var index = labelMap[key];
      if (index == null) {
        index = labels.length;
        labels.push(key);
        labelMap[key] = index;
      }
      row[index] = entry[key];
    }
  }
  return result;    
}