在JavaScript中创建和填充具有固定宽度的数组

时间:2011-02-27 02:51:02

标签: javascript arrays json

我有一个这种格式的输入数组:

[[timestamp, jobid, time to completion],[..]]

数据来自SQL DB,按时间戳和jobid分组,因此数组如下所示:

[  
[1, 30, 400],  
[1, 31, 200],  
[2, 29, 300],  
..  
]

我想为每个jobid创建一个包含一列的新数组,而不是每个job id的一行,即每个时间戳一行。

所以,我编写了一些迭代通过上面数组的代码,并填充了一个新的数组,很简单,除了结果数组不是固定的宽度,也就是说,结果如下:

[  
[1, 400, 200],  
[2, 300]  
..  
]

这使得我无法说来自[1]的值是作业ID 30,所以我不能有一个有意义的标题行。 我想要的是这种格式的数据:

timestamp, jobid29, jobid30, jobid31  
[  
[1, 0, 400, 200],  
[2, 300, 0, 0],  
..  
]

不幸的是,我无法输出地图。

我怎样才能做到这一点?我知道我必须经过一次输入以获得所有不同的工作,然后我想我会将每个jobid映射到一个位置等,我想知道这是否是最好的方法?

谢谢。

1 个答案:

答案 0 :(得分:1)

我的解决方案使用两个数组和两个映射,并提供了大量优化的可能性。这是一个粗略的草图:

  1. 按jobID对数组进行排序。 (我们称之为“jobList”)

  2. 保留一个键入唯一时间戳的“地图”。 ( “timeStampMap”)。地图应包含每个唯一时间戳的一个条目。

  3. 保留另一组唯一时间戳并对其进行排序。 ( “timeList”)

  4. “timeStampMap”中的每个项目都会在该时间戳值上保留另一个作业地图

  5. 迭代时间戳列表中的每个值。

    在每次迭代中,迭代jobList中的每个作业。   如果作业位于相应的时间戳映射输出job.completionTime

    否则,输出零。

  6. 我在下面展示的代码有两种可能的优化方式。 1.您可以将输入数组用作“jobList”而无需复制它。 你可能会把地图图组合成一张大地图。

    function jobSorter(a,b) {
        return a.jobID - b.jobID;
    }
    
    function numberSort(a,b) {
        return a - b;
    }
    
    
    function buildSortedArray(yourArray) {
    
        var index, j, item;
        var jobList = []; // array of {jobID, timeStamp, timeComp};
        var timeStampMap = {};
        var timeStampList = [];
        var key, jobkey;
        var output = [];
    
        // loop through every item in the array
        for (index = 0; index < yourArray.length; index++) {
            item = yourArray[index];         
    
            // push each item into a "job list"
            job = {jobID: item[1], timeStamp: item[0], timeComp: item[2]};
            jobList.push(job);
    
            // now use both a map and a list to keep track of all the unique timestamps
            key = "$timestamp$" + job.timeStamp.toString();
    
            if (timeStampMap[key] === undefined) {
                timeStampMap[key] = {};
                timeStampMap[key].jobMap = {};
    
                timeStampList.push(job.timeStamp); // keep another timestamp array that we can sort on
            }
    
            // add this job to the timestamp
            jobkey = "$jobid$" + job.jobID.toString();
            timeStampMap[key].jobMap[jobkey] = job;
        }
    
        // let's do some sorting
        timeStampList.sort(numberSort); // timeStampList is now in ascending order
        jobList.Sort(jobSorter);        // jobList is now in ascending order
    
    
        for (index = 0; index < timeStampList.length; index++) {
            item = [];
    
            item.push(timeStampList[index]);
            for (j = 0; j < jobList.length; j++) {
    
                key = "$timestamp$" + timeStampList[index].toString();
                jobkey = "$jobid$"  + jobList[j].toString();
    
                if (timeStampMap[key].jobMap[jobkey]) {
                    item.push(timeStampMap[key].jobMap[jobkey].timeComp);
                }
                else {
                  item.push(0);
                }
            }
    
            output.push(item);
        }
    
    
        return output;
    }