1

現在、次のようなオブジェクトの配列があり、エントリは日付と時刻で並べられています。

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

この順序でデータを取得すると、次のようなテーブルをレイアウトできます。

テーブルとしてレイアウトされたデータ

ありがとう、助けていただければ幸いです。

4

6 に答える 6

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

働くフィドル

于 2013-06-25T00:34:27.830 に答える
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));

もちろん、 、 、 、 、、などのgroupByロジックを記述する必要があるため、実際のコードははるかに大きくなります (100 行強のコード) 。toArrayzipAllmapgetHeadergetRowgetTable

幸運なことに、私はこのすべてのことを書きに行く時間がありました。したがって、動作するデモができました: http://jsfiddle.net/hZFJw/

私のコードを参照して、それがどのように機能するかを理解しようとすることをお勧めします。1つの答えで説明するには多すぎます。

注:私の解決策は、100 行を超えるコードになる場合があります。ただし、次の理由から、これはまだ単純なソリューションです。

  1. テーブルを生成する実際のコードはわずか 4 行の長さで、非常に簡単に理解できます。
  2. コードの残りの部分は、 、 、 などの再利用可能な関数で構成されてgroupByzipAllますmap。これらの関数は非常に小さく、簡単に理解できます。
  3. 全体として、プログラムを再利用可能な関数に抽象化することで、プログラムのサイズが増加しました。ただし、プログラムの複雑さは大幅に減少しました。

他のほとんどの回答と同様に、命令型のスタイルで問題に取り組むことで、同じ結果を得ることができます。ただし、そうするとプログラムが理解しにくくなります。私のコードを他の回答と比較して、自分の目で確かめてください。

于 2013-06-25T05:01:09.470 に答える
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;
            }
        }
    }

}
于 2013-06-25T00:36:22.657 に答える
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]);

jsFiddle でこの例を試してください。

于 2014-12-18T12:20:55.950 に答える
0

この配列を「行」にレイアウトするために並べ替えたいので、データを [この線形表現に] 並べ替える必要があります。その順序でデータを取得すると、テーブルをレイアウトできます

いいえ、そうである必要はありません。実際、これは 1 ステップ多すぎます。中間結果の順序はまったく意味がありません。代わりにすべきことは、(entries-per-day-) リストの (weekday-) リストを作成することです:

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);
}

これで、2 次元フォーマットが完成しました。まあ、あなたが望むテーブルにそれを入れるためにそれを転置する必要があるかもしれませんが、それもそれほど複雑ではありません:

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);
}
于 2013-06-25T01:27:21.483 に答える