Here is my function for determining if a given timecode in the buffer of an html5 video element (learned about this here).
I think there must be a faster way. Maybe a binary search over the start times?
I considered an interval tree, but the cost to maintain that data structure seems excessive given a system level data structure is provided.
isTimecodeInBuffer = function( _tc ) {
var r = $(html5VideoEl).buffered;
var i;
var iMax = r.length;
var within = false;
//todo: better seek here
for (i=0; i<iMax; ++i) {
if (_tc >= r.start(i) && _tc < r.end(i)) {
within = true;
break;
}
}
return within;
};
You can do this with a standard binary search that is slightly modified to test for matching a time range, rather than an exact match. It's not worth storing any kind of data structure, since the data will change quite frequently as additional data is buffered.
function bufferedGreater(haystack, index, value) {
return haystack.end(index) <= value;
}
function bufferedLess(haystack, index, value) {
return haystack.start(index) > value;
}
function binarySearch(haystack, needle, greaterThan, lessThan) {
var minIndex = 0,
maxIndex = haystack.length - 1,
currentIndex;
while (minIndex <= maxIndex) {
currentIndex = Math.floor((minIndex + maxIndex) / 2);
if (greaterThan(haystack, currentIndex, needle)) {
minIndex = currentIndex + 1;
} else if (lessThan(haystack, currentIndex, needle)) {
maxIndex = currentIndex - 1;
} else {
return currentIndex;
}
}
return -1;
}
var buffered = binarySearch(video.buffered, 10, bufferedGreater, bufferedLess) >= 0;
There is a working demo at http://jsbin.com/vifedogi/1/edit?html,js,console,output
Note: you'll want to access the buffered object directly on the video element, not on the jQuery object, like var r = html5VideoEl.buffered;
Related
i was trying to implement the A* algorithm and followed the wikipedia pseudo code to make this.
when i pass a predefined object pixel to the a funtion getG() it says that the object is null. I'm sorry if i am not pointing to a specific problem but i am not even sure how to really specify the problem by name. i have tried commenting out the code to increase readability.
git repository link of the whole project - https://github.com/NirobNabil/WhirlWind
(things are a little messy here because i didn't use github at first and i uploaded it just a little ago for posting the problem)
[ i'm actually making this to use a* to find path for my bot which is powered by arduino. thats why i'm using involt. ]
here goes the code,
$(function() {
// define the height, width and bot size in centemeter
total_width = 200;
total_height = 200;
bot_size = 20;
total_box = (total_height / bot_size) * (total_width / bot_size);
box_in_x = total_width / bot_size;
box_in_y = total_height / bot_size;
//populating the pixels array
populate(total_width / bot_size, total_height / bot_size, "UND");
pathfind(pixels, pixels[13], pixels[pixels.length - 1]);
})
var pixels = []; //an array to hold all the objects(the grid)
var obstacles = []; //array to hold the obstacles
function pixel(X, Y, obs) {
this.X_co_ordinate = X;
this.Y_co_ordinate = Y;
this.state = obs; //availale states OPN, UND, OBS, DIS, NULL
this.g = 0;
this.h = 0;
this.f = 0;
this.last = null;
} //every block in the grid is a pixel
//01719372596
function populate(height, width, obs_val = "UND") {
pixels[0] = new pixel(0, 10, obs_val);
for (h = height, i = 0; h >= 0; h--) {
for (w = 0; w < width; w++, i++) {
var temp_obs = new pixel(w, h, obs_val);
temp_obs.last = pixels[0];
pixels[i] = temp_obs; //saving temp_pixel object to pixels array
}
}
} //populating the grid AKA pixels with pixel objects or blocks
// this funtion is where the problem shows up
function getG(current, start) {
let g = 1;
while (current != start && current.last != start && current) {
current = current.last;
g++;
}
return g;
} //get the g val(cost to come to this pixel from the start) of the current pixel
function getH(current, end) {
let I = Math.abs(current.X_co_ordinate - end.X_co_ordinate) + Math.abs(current.Y_co_ordinate - end.Y_co_ordinate);
return I;
} //get the h val(heuristic) of the current pixel
function getF(start, current, end) {
let G = getG(current, start);
let H = getH(current, end);
return G + H;
} //get the f val(total) of the current pixel
function lowFinArray(arr, start, end) {
// here arr is the grid/pixel
let current_low = arr[0];
for (let i = 0; i < arr.length; i++) {
let getF1 = getF(start, current_low, end);
let getF2 = getF(start, arr[i], end);
if (getF1 < getF2) {
current_low = arr[i];
}
}
console.log("current low");
console.log(current_low);
return current_low;
}
function getneighbours(grid, current) {
let neightbours = [];
neightbours.push(grid[getIndex(current.X_co_ordinate - 1, current.Y_co_ordinate)]);
neightbours.push(grid[getIndex(current.X_co_ordinate + 1, current.Y_co_ordinate)]);
neightbours.push(grid[getIndex(current.X_co_ordinate, current.Y_co_ordinate - 1)]);
neightbours.push(grid[getIndex(current.X_co_ordinate, current.Y_co_ordinate + 1)]);
/*
for(i=0; i<neightbours.length; i++){
neightbours[i].last = current;
}*/
console.log("neightbours");
console.log(neightbours);
return neightbours;
} //get the neighbour pixels of the current pixel
//main algo
function pathfind(grid, start, end) {
let closedSet = [];
let openSet = [];
openSet.push(start);
let current = start;
//trying to debug
console.log("low F in arr");
console.log(lowFinArray(grid, start, end));
console.log(start);
console.log(current);
console.log(end);
console.log(grid);
let x = 0;
while (openSet.length > 0) {
//trying to debug
console.log("executed " + (x++));
console.log("openset");
console.log(openSet);
current = lowFinArray(grid, start, end); //assigning the pixel with lowest f val to current
console.log("current");
console.log(current);
if (current == end) {
console.log(getPath(current));
}
let neighbours = getneighbours(grid, current);
for (let i = 0; i < neighbours.length; i++) {
let neighbour = neighbours[i];
if (closedSet.includes(neighbour)) {
continue;
}
if (!openSet.includes(neighbours)) {
openSet.push(neighbours);
}
//console.log(current);
let getg = getG(current, start);
let geth = getH(current, end);
//console.log(getg);
let tGscore = getg + geth; //here getH is being used as a distance funtion
if (tGscore >= getg) {
continue;
}
neighbour.last = current;
neighbour.g = tGscore;
neighbour.f = getF(neighbour);
}
if (x > 10) {
return 0;
}; //the loop was running forever so i tried this to stop the loop after 10 iterations
}
}
function getPath(current) {
let path = [current];
while (current.last != null) {
path.push(current.last);
}
return path;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
and here is what the console says,
Uncaught TypeError: Cannot read property 'last' of null
at getG (app.js:226)
at getF (app.js:241)
at lowFinArray (app.js:249)
at pathfind (app.js:292)
at HTMLDocument.<anonymous> (app.js:92)
at mightThrow (jquery-3.1.1.js:3570)
at process (jquery-3.1.1.js:3638)
You're doing your checks in the wrong order:
while (current != start && current.last != start && current) {
There's no point in using && current after you've already used current.last.
Perhaps changing the order would solve the problem. It will at least get rid of your current error:
while (current && current != start && current.last != start) {
Regarding the title of this question:
In javascript, after i pass a non null object to a funtion it says the object is null
It may very well be non-null 100% of the time you pass it into the function, but you are repeatedly overwriting its parameter within the function, so all bets are off.
I'm interested in using the JavaScript WebAudioAPI to detect song beats, and then render them in a canvas.
I can handle the canvas part, but I'm not a big audio guy and really don't understand how to make a beat detector in JavaScript.
I've tried following this article but cannot, for the life of me, connect the dots between each function to make a functional program.
I know I should show you some code but honestly I don't have any, all my attempts have failed miserably and the relevant code it's in the previously mentioned article.
Anyways I'd really appreciate some guidance, or even better a demo of how to actually detect song beats with the WebAudioAPI.
Thanks!
The main thing to understand about the referenced article by Joe Sullivan is that even though it gives a lot of source code, it's far from final and complete code. To reach a working solution you will still need both some coding and debugging skills.
This answer draws most of its code from the referenced article, original licensing applies where appropriate.
Below is a naïve sample implementation for using the functions described by the above article, you still need to figure out correct thresholds for a functional solution.
The code consists of preparation code written for the answer:
reading a local file over the FileReader API
decoding the file as audio data using the AudioContext API
and then, as described in the article:
filtering the audio, in this example with a low-pass filter
calculating peaks using a threshold
grouping interval counts and then tempo counts
For the threshold I used an arbitrary value of .98 of the range between maximum and minimum values; when grouping I added some additional checks and arbitrary rounding to avoid possible infinite loops and make it an easy-to-debug sample.
Note that commenting is scarce to keep the sample implementation brief because:
the logic behind processing is explained in the referenced article
the syntax can be referenced in the API docs of the related methods
audio_file.onchange = function() {
var file = this.files[0];
var reader = new FileReader();
var context = new(window.AudioContext || window.webkitAudioContext)();
reader.onload = function() {
context.decodeAudioData(reader.result, function(buffer) {
prepare(buffer);
});
};
reader.readAsArrayBuffer(file);
};
function prepare(buffer) {
var offlineContext = new OfflineAudioContext(1, buffer.length, buffer.sampleRate);
var source = offlineContext.createBufferSource();
source.buffer = buffer;
var filter = offlineContext.createBiquadFilter();
filter.type = "lowpass";
source.connect(filter);
filter.connect(offlineContext.destination);
source.start(0);
offlineContext.startRendering();
offlineContext.oncomplete = function(e) {
process(e);
};
}
function process(e) {
var filteredBuffer = e.renderedBuffer;
//If you want to analyze both channels, use the other channel later
var data = filteredBuffer.getChannelData(0);
var max = arrayMax(data);
var min = arrayMin(data);
var threshold = min + (max - min) * 0.98;
var peaks = getPeaksAtThreshold(data, threshold);
var intervalCounts = countIntervalsBetweenNearbyPeaks(peaks);
var tempoCounts = groupNeighborsByTempo(intervalCounts);
tempoCounts.sort(function(a, b) {
return b.count - a.count;
});
if (tempoCounts.length) {
output.innerHTML = tempoCounts[0].tempo;
}
}
// http://tech.beatport.com/2014/web-audio/beat-detection-using-web-audio/
function getPeaksAtThreshold(data, threshold) {
var peaksArray = [];
var length = data.length;
for (var i = 0; i < length;) {
if (data[i] > threshold) {
peaksArray.push(i);
// Skip forward ~ 1/4s to get past this peak.
i += 10000;
}
i++;
}
return peaksArray;
}
function countIntervalsBetweenNearbyPeaks(peaks) {
var intervalCounts = [];
peaks.forEach(function(peak, index) {
for (var i = 0; i < 10; i++) {
var interval = peaks[index + i] - peak;
var foundInterval = intervalCounts.some(function(intervalCount) {
if (intervalCount.interval === interval) return intervalCount.count++;
});
//Additional checks to avoid infinite loops in later processing
if (!isNaN(interval) && interval !== 0 && !foundInterval) {
intervalCounts.push({
interval: interval,
count: 1
});
}
}
});
return intervalCounts;
}
function groupNeighborsByTempo(intervalCounts) {
var tempoCounts = [];
intervalCounts.forEach(function(intervalCount) {
//Convert an interval to tempo
var theoreticalTempo = 60 / (intervalCount.interval / 44100);
theoreticalTempo = Math.round(theoreticalTempo);
if (theoreticalTempo === 0) {
return;
}
// Adjust the tempo to fit within the 90-180 BPM range
while (theoreticalTempo < 90) theoreticalTempo *= 2;
while (theoreticalTempo > 180) theoreticalTempo /= 2;
var foundTempo = tempoCounts.some(function(tempoCount) {
if (tempoCount.tempo === theoreticalTempo) return tempoCount.count += intervalCount.count;
});
if (!foundTempo) {
tempoCounts.push({
tempo: theoreticalTempo,
count: intervalCount.count
});
}
});
return tempoCounts;
}
// http://stackoverflow.com/questions/1669190/javascript-min-max-array-values
function arrayMin(arr) {
var len = arr.length,
min = Infinity;
while (len--) {
if (arr[len] < min) {
min = arr[len];
}
}
return min;
}
function arrayMax(arr) {
var len = arr.length,
max = -Infinity;
while (len--) {
if (arr[len] > max) {
max = arr[len];
}
}
return max;
}
<input id="audio_file" type="file" accept="audio/*"></input>
<audio id="audio_player"></audio>
<p>
Most likely tempo: <span id="output"></span>
</p>
I wrote a tutorial here which shows how to do this with the javascript Web Audio API.
https://askmacgyver.com/blog/tutorial/how-to-implement-tempo-detection-in-your-application
Outline of Steps
Transform Audio File into an Array Buffer
Run Array Buffer Through Low Pass Filter
Trim a 10 second Clip from the Array Buffer
Down Sample the Data
Normalize the Data
Count Volume Groupings
Infer Tempo from Groupings Count
This code below does the heavy lifting.
Load Audio File Into Array Buffer and Run Through Low Pass Filter
function createBuffers(url) {
// Fetch Audio Track via AJAX with URL
request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function(ajaxResponseBuffer) {
// Create and Save Original Buffer Audio Context in 'originalBuffer'
var audioCtx = new AudioContext();
var songLength = ajaxResponseBuffer.total;
// Arguments: Channels, Length, Sample Rate
var offlineCtx = new OfflineAudioContext(1, songLength, 44100);
source = offlineCtx.createBufferSource();
var audioData = request.response;
audioCtx.decodeAudioData(audioData, function(buffer) {
window.originalBuffer = buffer.getChannelData(0);
var source = offlineCtx.createBufferSource();
source.buffer = buffer;
// Create a Low Pass Filter to Isolate Low End Beat
var filter = offlineCtx.createBiquadFilter();
filter.type = "lowpass";
filter.frequency.value = 140;
source.connect(filter);
filter.connect(offlineCtx.destination);
// Render this low pass filter data to new Audio Context and Save in 'lowPassBuffer'
offlineCtx.startRendering().then(function(lowPassAudioBuffer) {
var audioCtx = new(window.AudioContext || window.webkitAudioContext)();
var song = audioCtx.createBufferSource();
song.buffer = lowPassAudioBuffer;
song.connect(audioCtx.destination);
// Save lowPassBuffer in Global Array
window.lowPassBuffer = song.buffer.getChannelData(0);
console.log("Low Pass Buffer Rendered!");
});
},
function(e) {});
}
request.send();
}
createBuffers('https://askmacgyver.com/test/Maroon5-Moves-Like-Jagger-128bpm.mp3');
You Now Have an Array Buffer of the Low Pass Filtered Song (And Original)
It's comprised of a number of entries, sampleRate (44100 multiplied by the number of seconds of the song).
window.lowPassBuffer // Low Pass Array Buffer
window.originalBuffer // Original Non Filtered Array Buffer
Trim a 10 Second Clip from the Song
function getClip(length, startTime, data) {
var clip_length = length * 44100;
var section = startTime * 44100;
var newArr = [];
for (var i = 0; i < clip_length; i++) {
newArr.push(data[section + i]);
}
return newArr;
}
// Overwrite our array buffer to a 10 second clip starting from 00:10s
window.lowPassFilter = getClip(10, 10, lowPassFilter);
Down Sample Your Clip
function getSampleClip(data, samples) {
var newArray = [];
var modulus_coefficient = Math.round(data.length / samples);
for (var i = 0; i < data.length; i++) {
if (i % modulus_coefficient == 0) {
newArray.push(data[i]);
}
}
return newArray;
}
// Overwrite our array to down-sampled array.
lowPassBuffer = getSampleClip(lowPassFilter, 300);
Normalize Your Data
function normalizeArray(data) {
var newArray = [];
for (var i = 0; i < data.length; i++) {
newArray.push(Math.abs(Math.round((data[i + 1] - data[i]) * 1000)));
}
return newArray;
}
// Overwrite our array to the normalized array
lowPassBuffer = normalizeArray(lowPassBuffer);
Count the Flat Line Groupings
function countFlatLineGroupings(data) {
var groupings = 0;
var newArray = normalizeArray(data);
function getMax(a) {
var m = -Infinity,
i = 0,
n = a.length;
for (; i != n; ++i) {
if (a[i] > m) {
m = a[i];
}
}
return m;
}
function getMin(a) {
var m = Infinity,
i = 0,
n = a.length;
for (; i != n; ++i) {
if (a[i] < m) {
m = a[i];
}
}
return m;
}
var max = getMax(newArray);
var min = getMin(newArray);
var count = 0;
var threshold = Math.round((max - min) * 0.2);
for (var i = 0; i < newArray.length; i++) {
if (newArray[i] > threshold && newArray[i + 1] < threshold && newArray[i + 2] < threshold && newArray[i + 3] < threshold && newArray[i + 6] < threshold) {
count++;
}
}
return count;
}
// Count the Groupings
countFlatLineGroupings(lowPassBuffer);
Scale 10 Second Grouping Count to 60 Seconds to Derive Beats Per Minute
var final_tempo = countFlatLineGroupings(lowPassBuffer);
// final_tempo will be 21
final_tempo = final_tempo * 6;
console.log("Tempo: " + final_tempo);
// final_tempo will be 126
Let's say I have a simple array like this:
var myArr = [0,1,2,3,4,5,6,7,8,9]
I'd like to extract a number of elements, starting from a specific index, like this:
myArr.getElementsFromIndex(index, numberOfElements)
where, unlike .slice(), if we hit the last index, elements from the start of the array should be returned instead (so that the total number of elements returned will always be respected). Either pure javascript or a library like underscore/lodash can be used.
Examples:
myArr.getElementsFromIndex(3, 5)
should return[3,4,5,6,7]
and
myArr.getElementsFromIndex(8, 5)
should return [8,9,0,1,2]
Use the below code
var myArr = [0,1,2,3,4,5,6,7,8,9];
function getElementsFromIndex(startIndex, num) {
var elems = [];
for(var iter = 0; iter<num; iter++) {
if(startIndex >= myArr.length) {
while(startIndex >= myArr.length) {
startIndex -= myArr.length;
}
}
elems.push(myArr[startIndex]);
startIndex++;
}
return(elems);
}
Array#slice takes a start and end index (not a start index and a number of elements).
Array#splice does what you want, except for the wrapping around (but also modifies the original array).
You can write a wrapper function using slice (which will not modify the original array):
function getElementsFromIndex(arr, start, numElements) {
if(start + numElements > arr.length) {
var endOfArr = arr.slice(start, arr.length);
var elementsFound = arr.length - start;
var restElements = getElementsFromIndex(arr, 0, numElements - elementsFound);
return endOfArr.concat(restElements);
}
return arr.slice(start, start + numElements);
}
This function returns what you require (see example), and even wraps around multiple times, if needed.
If you want to tie the function to arrays, in order to use it as you propose (ie. myArr.getElementsFromIndex(start, numElements)), you can add it to Array's prototype. You might want to look up arguments for/against modifying prototypes of built-in types, though.
Array.prototype.getElementsFromIndex = function(start, numElements) {
if(start + numElements > this.length) {
var endOfArr = this.slice(start, this.length);
var elementsFound = this.length - start;
return endOfArr.concat(this.getElementsFromIndex(0, numElements - elementsFound));
}
return this.slice(start, start + numElements);
};
See example of the last one here.
Add this to your js code:
Array.prototype.getElementsFromIndex = function (start, len) {
var newArray = [],
origArray = this,
i = start;
while (newArray.length < len) {
newArray.push(origArray[i++]);
if (i >= origArray.length)
i = 0;
}
return newArray;
}
You can use it exactly the way you wanted:
var myArr = [0,1,2,3,4,5,6,7,8,9];
alert(myArr.getElementsFromIndex(8, 5));
JSFIDDLE DEMO: http://jsfiddle.net/x6oy0krL/1
Maybe some people will say that it is not right to extend objects like Array, documentElement and so on, but the result here is as the OP wanted.
I want to say that the original array will not be modified, too.
Just concatenate the array to itself, then use slice:
function sliceWrap(arr, start, num) {
return arr.concat(arr).slice(start, start+num);
}
Another approach, which wraps around:
function sliceWrap2(arr, start, num) {
var result = [], i, end = start+num, len = arr.length;
for (i=start; i<end; i++) {
result.push(arr[i % len]);
}
return result;
}
I'm modifying the jquery ui slider. I have certain "stops" I want the user to be able to slide to, expressed as a percentage of the slider's overall width. So, for example, if I have 3 stops, they will be distributed evenly at 0, 50, and 100 (%). I store these in an array [0,50,100].
When the user drags the slider and releases, I capture the slider's current value. So if he scrolled 56% of the way across the bar, his stopVal is 56.
How do I write a function that will then determine which number in the array this stopVal is closest to? Here's my code:
var optValArr = [0,50,100];
function slideStop( event, ui ) {
var stopVal = ui.value;
//NOW NEED TO FIND CLOSEST ARRAY VALUE TO stopVal
}
This function will let you do that:
Array.prototype.closest = function(value) {
var i;
function diff(n) {
var diff = n - value;
return diff < 0 ? -diff : diff;
}
var found = this[0],
mindiff = diff(found);
for (i = 1 ; i < this.length ; i++) {
var currentdiff = diff(this[i]);
if (currentdiff < mindiff) {
found = this[i];
mindiff = diff(found);
}
}
return found;
}
Now you can do this:
var optValArr = [0,50,100];
function slideStop( event, ui ) {
var stopVal = ui.value;
//NOW NEED TO FIND CLOSEST ARRAY VALUE TO stopVal
stopVal = optValArr.closest(stopVal);
}
NOTE: Some people consider defining prototypes for native types as dangerous as it can cause conflicts if two libraries do the same (just like global variable). If you are writing a public library you should therefore avoid adding to the prototypes of native types.
Try This:
var optValArr = [0,50,100];
function slideStop( event, ui ) {
var stopVal = ui.value;
var diff=101;
var val =0;
for(var i =0; i < optValArr.length; i++){
var tmpDiff = Math.abs(stopVal - optValArr[i]);
if(tmpDiff < diff){
diff=tmpDiff;
val = optValArr[i]
}
}
}
slideStop("something", {"value":20});
Demo: http://jsfiddle.net/ggzZj/
var optValArr = [0,50,100];
function slideStop( event, ui ) {
var stopVal = ui.value;
var closestVal = optValArr.reduce(function (memo, curr) {
var currDiff = Math.abs(curr - stopVal),
memoDiff = Math.abs(memo - stopVal)
return memoDiff < currDiff ? memoDiff : currDif
})
}
Another common definition of "closer" is based on the square of the difference. But, you could do that by simply adding the number that you want in your original array like this:
[10,40,50, my_number]
Then, sort your array and then you choice if you want the closest position from the right or the left.
What do you think?
I have an array of objects gAllMedicalFilesClaimantsArray with 2 properties (UserID & UserInfo)
For example:
gAllMedicalFilesClaimantsArray[0].UserID = "111";
gAllMedicalFilesClaimantsArray[0].UserInfo = "AAA-111";
gAllMedicalFilesClaimantsArray[1].UserID = "222";
gAllMedicalFilesClaimantsArray[1].UserInfo = "BDD-478333";
What is the fastest way to check whether a specific UserID exists in the array using Jquery or Javascript because gAllMedicalFilesClaimantsArray has got 8000 records?
Thanks
var match = '222';
var matches = $.grep(myArray, function(el, index) {
return (el.UserID === match);
});
You can fasten the search process by using Binary Search algorithm if the array is sorted (e.g with respect to UserId).
function binarySearch(array, userid) {
var low = 0, high = array.length - 1,
i, comparison;
while (low <= high) {
i = parseInt((low + high) / 2, 10);
if (array[i].UserId < userid) { low = i + 1; continue; };
if (array[i].UserId > userid) { high = i - 1; continue; };
return array[i];
}
return null;
};
You can find the user of which ID is 12 by using the function:
var result = binarySearch(gAllMedicalFilesClaimantsArray, 12);
Something like this, I believe:
function exists(uid) {
var k = gAllMedicalFilesClaimantsArray.length;
uid = uid.toString(); // ensure the arg is a str (this can be omitted)
while (k--) {
if (gAllMedicalFilesClaimantsArray[k].UserID === uid) {
return true;
}
}
return false;
}
Is the array sorted by the UserID? If so, it can be improved either further by using a binary search; that would change this from O(n) to O(log n). Your example suggests it is. I found a good implementation of a binary search in JavaScript on the web, here. Here is the code if the site ever dies:
function binarySearch(items, value){
var startIndex = 0,
stopIndex = items.length - 1,
middle = Math.floor((stopIndex + startIndex)/2);
while(items[middle] != value && startIndex < stopIndex){
//adjust search area
if (value < items[middle]){
stopIndex = middle - 1;
} else if (value > items[middle]){
startIndex = middle + 1;
}
//recalculate middle
middle = Math.floor((stopIndex + startIndex)/2);
}
//make sure it's the right value
return (items[middle] != value) ? -1 : middle;
}
ExistsInArray(value, array){
for(var item in array){
if(item.UserId == value){
return true;
}
}
return false;
}
You can either prototype Array object, like this:
Array.prototype.exists = function(value, prop){
var i = null;
for (i in this)
if (this[i][prop] && this[i][prop] == value)
return true;
return false;
}
gAllMedicalFilesClaimantsArray.exists('222', 'UserID');