【问题标题】:Creating and populating an array with a fixed width in JavaScript在 JavaScript 中创建和填充具有固定宽度的数组
【发布时间】:2011-02-27 02:51:01
【问题描述】:

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

[[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,然后我想我会将每个 jobid 映射到一个位置等,我想知道这是否是最好的方法?

谢谢。

【问题讨论】:

    标签: javascript arrays json


    【解决方案1】:

    我的解决方案使用两个数组和两个映射,有很多优化的可能性。这是一个粗略的草图:

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

    2. 保留以唯一时间戳为键的“地图”。 (“时间戳映射”)。该地图应为每个唯一时间戳包含一个条目。

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

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

    5. 遍历时间戳列表中的每个值。

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

      否则,输出零。

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

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

    【讨论】:

    • 不错的解决方案。你能解释一下key = $timestamp$ + job.timeStamp.toString()的目的吗?概述表明这应该是key = job.timeStamp.toString()。 jobkey 也一样。
    • 糟糕,它应该是引号中的“$timestamp$”。同样,引号中的“$jobid$”。固定的。我喜欢为键添加唯一标识符的前缀有两个原因:1) 易于调试(在 firebug 中易于查看这些属性) 2) 使用文字数字作为对象属性名称并不合适。对数组感到困惑。
    • 我喜欢你的想法。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多