Reputation: 12175
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?
Upvotes: 0
Views: 64
Reputation: 538
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:
Upvotes: 0
Reputation: 3582
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;
}
Upvotes: 1
Reputation: 5190
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];
}
}
Upvotes: 0