我有一个当前像这样的对象数组,其中的条目按日期和时间排序:
var checkin_data = [
{id: 430, date: "2013-05-05", time: "08:24"},
{id: 435, date: "2013-05-06", time: "04:22"},
{id: 436, date: "2013-05-06", time: "05:36"},
{id: 437, date: "2013-05-06", time: "07:51"},
{id: 488, date: "2013-05-06", time: "08:08"},
{id: 489, date: "2013-05-06", time: "10:12"},
{id: 492, date: "2013-05-06", time: "13:18"},
{id: 493, date: "2013-05-06", time: "15:55"},
{id: 494, date: "2013-05-06", time: "18:55"},
{id: 498, date: "2013-05-06", time: "22:15"},
{id: 501, date: "2013-05-07", time: "11:40"},
{id: 508, date: "2013-05-07", time: "18:00"},
{id: 520, date: "2013-05-08", time: "04:48"},
{id: 532, date: "2013-05-09", time: "21:11"},
{id: 492, date: "2013-05-10", time: "11:45"},
{id: 601, date: "2013-05-11", time: "18:12"}
];
日期表示特定周的日期:我想对此数组进行排序,以便将其排列在“行”中,因此需要对数据进行重新排序,使其布局如下(请注意顺序日期):
var checkin_data = [
{id: 430, date: "2013-05-05", time: "08:24"},
{id: 435, date: "2013-05-06", time: "04:22"},
{id: 501, date: "2013-05-07", time: "11:40"},
{id: 520, date: "2013-05-08", time: "04:48"},
{id: 532, date: "2013-05-09", time: "21:11"},
{id: 492, date: "2013-05-10", time: "11:45"},
{id: 601, date: "2013-05-11", time: "18:12"},
{id: 436, date: "2013-05-06", time: "05:36"},
{id: 508, date: "2013-05-07", time: "18:00"},
{id: 437, date: "2013-05-06", time: "07:51"},
{id: 488, date: "2013-05-06", time: "08:08"},
{id: 489, date: "2013-05-06", time: "10:12"},
{id: 492, date: "2013-05-06", time: "13:18"},
{id: 493, date: "2013-05-06", time: "15:55"},
{id: 494, date: "2013-05-06", time: "18:55"},
{id: 498, date: "2013-05-06", time: "22:15"}
];
按顺序获取数据将允许我布置如下表格:
谢谢,任何帮助都将不胜感激。
答案 0 :(得分:1)
以下是使用功能方法的建议:
下面:
//first, we collapse the array into an array of buckets by day
half_sorted = checkin_data.reduce(function(accum,cur){
var bucket = new Date(cur.date).getDay();
accum[bucket].push(cur);
return accum;
},[[],[],[],[],[],[],[]]).map(function(day){
return day.sort(function(x,y){ // now we sort each bucket
return new Date("01-01-1990 "+x.time) - new Date("01-01-1990 "+y.time);
});
});
// At this point, we have an array with 7 cells looking like your table
// if we look at its columns.
// finally, we push to the result table.
var result = [];
var daysToClear = 7;
for(var i=0;daysToClear>0;i=(i+1)%7){
if(half_sorted[i] && half_sorted[i].length > 0){
result.push(half_sorted[i].pop());
}else if(half_sorted[i] && half_sorted[i].length === 0){
half_sorted[i] = null;
daysToClear--;
}
}
答案 1 :(得分:1)
首先,我认为你是以错误的方式解决这个问题。请参阅以下代码中的注释。
完全按照您的要求行事,这是一种方式:
// parsing the date strings ourselves avoids time zone problems
function dateFromString(string) {
var parts = string.split('-');
return new Date(parseInt(parts[0], 10),
parseInt(parts[1], 10) - 1,
parseInt(parts[2], 10));
}
以上是实用功能。
var i, l, dates = [[], [], [], [], [], [], []], item;
// place the objects into dow-sorted buckets
for (i = 0, l = checkin_data.length; i < l; i += 1) {
item = checkin_data[i];
dates[dateFromString(item.date).getDay()].push(item);
}
i = 0;
l = 0;
checkin_data = [];
while (true) { // instead of a for loop to handle the row-wrap manually
if (dates[i][l]) {
item = dates[i][l];
checkin_data.push(item);
}
i += 1;
if (i === 7) {
if (!item) {
break; // we had a complete row with no data
}
item = undefined;
l += 1;
i = 0;
}
}
checkin_data
现在按您请求的顺序排序。
注意:你真的不需要第二个循环,因为它正在完成大部分工作,你必须再次使用提供的数组。因此,在编写表的例程中,只需使用第一个循环创建的数据结构。你当然需要一个稍微不同的救助策略,因为你不想创建一个额外的空行,但我会把它留给你。
经过一番思考后,我想出了另一种方法,如果你不介意为你的对象添加新的密钥:
function dateFromString(string) {
var parts = string.split('-');
return new Date(parseInt(parts[0], 10),
parseInt(parts[1], 10) - 1,
parseInt(parts[2], 10));
}
var i, l, counts = [0, 0, 0, 0, 0, 0, 0], item, dow;
for (i = 0, l = checkin_data.length; i < l; i += 1) {
item = checkin_data[i];
dow = dateFromString(item.date).getDay();
item.sortKey = ++counts[dow] * 7 + dow;
}
checkin_data.sort(function(a, b) {
return a.sortKey - b.sortKey;
});
答案 2 :(得分:0)
我想出了一个解决方案,也许不是最优雅的解决方案,但它正在发挥作用:
var sorted_data = [], elements_to_dump = [], i, j, tmp;
while (checkin_data.length > 0) {
for (i = 0; i < checkin_data.length; i++) {
if (checkin_data[i-1]) {
if (checkin_data[i-1].date === checkin_data[i].date) {
continue;
}
}
sorted_data.push(checkin_data[i]);
elements_to_dump.push(checkin_data[i].id);
}
for (j = 0; j < elements_to_dump.length; j++) {
for (i = 0; i < checkin_data.length; i++) {
if (checkin_data[i].id === elements_to_dump[j]) {
tmp = checkin_data.splice(i, 1);
break;
}
}
}
}
答案 3 :(得分:0)
我想对这个数组进行排序,以便在“行”中进行排序,因此数据需要重新排序[进入此线性表示]。按顺序获取数据将允许我布置表格
不,它不需要。实际上,这太过分了,中间结果的顺序完全没有意义。你应该做的是构建一个(工作日)列表(每日条目)列表:
var days = [];
for (var i=0, date=null, day; i<checkin_data.length; i++) {
var entry = checkin_data[i];
if (entry.date !== date)
days.push(day = []);
day.push(entry);
}
就是这样,你现在有了二维格式。好吧,也许你需要将它转换成你想要的表格,但这也不是太复杂:
var header = [],
table = [header]; // or create a DOM or a HTML string or whatever
for (var i=0; i<days.length; i++)
header.push(days[i][0].date /* or the weekday name? */);
for (var r=0; !done; r++) {
var row = [],
done = true;
// create cells:
for (var i=0; i<days.length; i++)
if (days[i].length > r) {
row[i] = days[i][r].time;
done = false;
} else
row[i] = "";
}
if (!done)
table.push(row);
}
答案 4 :(得分:0)
你要做的事情很简单。这就是我要做的事情:
var groups = groupBy(checkin_data, "date"); // groups items based on date
var table = zipAll.apply(null, toArray(groups)); // zips corresponding elements
// of each group into an array
在此之后,您可以按如下方式创建表格:
var header = getHeader(groups), rows = map(table, getRow);
document.body.appendChild(getTable(header, rows));
当然,实际代码会更大(超过100行代码),因为您需要为groupBy
,toArray
,zipAll
,{{编写逻辑1}},map
,getHeader
,getRow
等
幸运的是,我有时间去写所有这些东西。因此,您现在有一个工作演示:http://jsfiddle.net/hZFJw/
我建议您浏览我的代码并尝试了解它是如何工作的。在一个答案中解释太多了。
注意:我的解决方案可能超过100行代码。然而,它仍然是一个简单的解决方案,因为:
getTable
,groupBy
和zipAll
。这些功能非常小而且易于理解。通过像大多数其他答案那样以命令式方式处理问题,您可以获得相同的结果。但这样做会使程序更难理解。将我的代码与其他答案进行比较,亲眼看看。
答案 5 :(得分:0)
您可以使用Alasql JavaScript库对数组进行排序。
alasql.fn.WEEKDAY = function(d) { // User-defined function
return (new Date(d)).getDay();
};
var res = alasql('SELECT *, WEEKDAY(date) AS dow FROM ? ORDER BY dow', [checkin_data]);
试试这个例子at jsFiddle。