0

I've got an input array in this format:

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

the data is from a SQL DB, grouped by both timestamp, and jobid, so the array looks like:

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

I would like to create a new array with one column for every jobid, instead of one row with every job id, that is, a single row per timestamp.

So, I wrote some code that iterated through the above array, and populated a new array, simple enough, except, the result array isn't fixed width, that is, the result looks like:

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

Which makes it impossible for me to say that values from [1] are job ID 30, so I can't have a meaningful header row. What I would like is, data in this format:

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

I can't output a map, unfortunately.

How can I achieve this? I know I'll haveto go through the input once to get all the distinct jobids, and then I guess I'd map each jobid to a position, etc, I'm wondering if this is the best way?

Thank you.

1 Answer 1

1

My solution uses two arrays and two maps with plenty of possibilities for optimizations. Here's a rough sketch:

  1. Sort your array by jobID. (let's call this the "jobList")

  2. Keep a "map" that is keyed on unique timestamps. ("timeStampMap"). The map should contain one entry for each unique timestamp.

  3. Keep another array of unique timestamps and sort it. ("timeList")

  4. Each item in the "timeStampMap" keeps another map of jobs on that timestamp value

  5. Iterate over each value in the timestamp list.

    Within each iteration, iterate over each job in the jobList. if the job is in the corresponding timestamp map output job.completionTime

    otherwise, output zero.

There are two possible optimizations to the code I show below. 1. You could likely use the input array as the "jobList" without having to copy it. 2. You could likely combine the map of maps into one large map.

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;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Nice solution. Could you explain the purpose of key = $timestamp$ + job.timeStamp.toString(). The overview suggests this should be key = job.timeStamp.toString(). Also same with jobkey.
Oops, it should be "$timestamp$" in quotes. Likewise, "$jobid$" in quotes. Fixed. I like prefixing unique identifier for the key for two reasons: 1) easy to debug (easy to see those properties in firebug) 2) doesn't feel right to use a literal number as an object property name. Get confused with arrays.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.