Question

I have read multiple posts on here in other languages, however it didn't quite help me.

Let's say I have an array, which could be anything from:

[0,1,2,4,5,6,7,10]

to:

[1194,1195,1199,1299]

What I need to do, is find out what numbers are missing within the sequence. These arrays coulr be out of order too.

Example 1 would result in:

"Missing Frames = 3, 8-9"

Example 2 would result in:

"Missing Frames = 1196-1198, 1200-1298"

Currently, I have found the missing frames, but I can't figure out how to format them like above strings, instead, I'm just building an array.

Here is what I've done so far:

DEMO: http://jsfiddle.net/qBcD6/2/

Any Ideas?

Was it helpful?

Solution

There is probably a more elegant way to do this, but this will do the job for you (jsfiddle demo):

filesArray = [1195, 1201, 1202, 1203, 1205, 1001, 1002, 1004];
filesArray.sort();
var arrayLength = filesArray.length;
var lastFrame = filesArray[arrayLength - 1];
var firstFrame = filesArray[0];
var loopLength = lastFrame - firstFrame;
var missingArrayIndex = 0;
var missingFrames = new Array();
var missingFramesString = "";
for (var i = 0; i <= loopLength; i++) {

    currentFrame = firstFrame + i;
    console.log("currentFrame is "+(currentFrame)+" and last frame was "+missingFrames[missingArrayIndex-1]);

    if (!isInArray(currentFrame, filesArray))
    {

        missingFrames[missingArrayIndex] = currentFrame;

        // if the currentFrame is not the last missingFrame+1, then it is new sequence

        if( currentFrame !== missingFrames[missingArrayIndex-1]+1)
        {
            missingFramesString = missingFramesString + currentFrame;

        }

    missingArrayIndex++;

    // if not a missing frame and the currentFrame-1 was a missingFrame then it is last of sequence
    } else if( currentFrame == missingFrames[missingArrayIndex-1] +1 )    {
        if (missingFramesString.indexOf(missingFrames[missingArrayIndex-1]) >= 0)
            missingFramesString = missingFramesString + ",";
        else missingFramesString = missingFramesString + "-" + missingFrames[missingArrayIndex-1] + ",";
    }
}

// remove last comma
missingFramesString = missingFramesString.replace(/,\s*$/, "");

$('body').html("Missing Frames = " + missingFramesString);

function isInArray(value, array) {
    return array.indexOf(value) > -1;
}

OTHER TIPS

Something like this? Mostly from memory, didnt get a chance to fully test against your fiddle..

var missingFormatted = missingFrames[0];
var current = missingFormatted;
for(var i = 1; i < missingFrames.length-1; i++)
{
    if(missingFrames[i]-current > 1)
    {
        if(missingFrames[i-1] != current)
            missingFormatted = missingFormatted + "-" + missingFrames[i-1];

        missingFormatted = missingFormatted + "," + missingFrames[i];
    }
}

Try this:

var frames = [0,1,2,4,5,6,7,10];

var convertIntArrayToStringsWithConsecutives = function(arr) {
    var i = 0, result = [];

    // Make sure we don't over-step the array
    for(i; i < arr.length - 1; i++) {
        // If next element is not consecutive
        if(arr[i + 1] !== (arr[i] + 1)) {
            // Print either single element when there is no gap
            if(arr[i] + 1 === arr[i+1] - 1) {
                result.push(arr[i] + 1);
            } else {
                // Or the two elements either end of the gap
                result.push((arr[i] + 1) + '-' + (arr[i+1]-1));
            }
        }
    }
    return result;
}

$('body').html("Missing Frames = " + convertIntArrayToStringsWithConsecutives(frames.sort(function (a,b) {
return a - b;
}))).toString());

Tested here:

http://jsfiddle.net/5k86J/6/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top