I have an array like so [1,9,9,9,9,9]. I want to increment this array by one and return [2,0,0,0,0,0]. Here's the catch - you can't join() or concat(). You cannot change the array in any way other than adding to it. However, you can reverse it but I'm not sure how much that would help
Also, here are a few other examples;
[1,8,9] => [1,9,0];
[1,2,3,9,1] => [1,2,3,9,2];
[5,7,9,9] => [5,8,0,0];
The result can only return an array with single digits.
Basically, pretend that the array is a single number and you're adding 1 to it. Again, no joining, splitting, turning into a string.. etc.
Ideally, I would like a classic loop solution or possibly a recursion solution. Thank you!
here is my repl.it https://repl.it/#CharChar5/Code-Challenge
Thank you in advance for your help and I'm terribly sorry if my questions title is too long and confusing. I'm certainly working on formatting better questions and building a stronger rep on SO.
https://repl.it/#CharChar5/Code-Challenge
Currently this is my code:
jjChallenge=(j)=>{
const len = j.length;
const newArray = [];
for(var i = 0; i<j.length; i++){
if (j[i] == 9) {
if(j[i-1] == 9) {
n = 0;
} else {
newArray[i-1] = newArray[i-1] + 1;
n = 0;
}
newArray.push(n);
} else {
newArray.push(j[i]);
}
}
console.log(newArray)
}
jjChallenge([2,9,9,9]) //works and returns [3,0,0,0]
//[2,9,8,9] doesnt work and returns [3,0,9,0]
Reverse it and increment with carry and then reverse it back
Something like
eg
function incrementIntArray(arr) {
var reverseArray = arr.reverse();
var newReverseArray = [];
var carry = false;
for (var i = 0; i < arr.length; i++) {
var curNum = reverseArray[i];
if (i == 0 || carry) curNum++;
if (curNum > 9) {
carry = true;
curNum = 0;
} else {
carry = false;
}
newReverseArray[i] = curNum;
}
return newReverseArray.reverse();
}
var arr1 = [1, 8, 9];
var arr2 = [1, 2, 3, 9, 1];
var arr3 = [5, 7, 9, 9];
console.log(incrementIntArray(arr1)); //outputs [1,9,0]
console.log(incrementIntArray(arr2)); //outputs [1,2,3,9,2]
console.log(incrementIntArray(arr3)); //outputs [5,8,0,0]
Your code was trying to carry, but it's difficult to carry when coming from the top down, hence the reverse and then its easier to carry from bottom up
Here ya go:
jjChallenge=(arr)=>{
newArray=arr.map((element) => {
return element==9?0:element+1
})
return newArray
}
jjChallenge([2,9,9,9])
Just sum the digits up and then plus one. After that, split it.
Simple and Clean that complies with
you can't join() or concat(). You cannot change the array in any way other than adding to it.
addOne = (data) => {
let sum = 0, digit = data.length - 1
data.forEach(n => sum += n * (10 ** digit--))
return (sum + 1).toString().split("")
}
console.log(addOne([1,8,9]))
console.log(addOne([1,2,3,9,1]))
console.log(addOne([5,7,9,9]))
Related
I was asked recently what was the most efficient way to reverse an array in Javascript. At the moment, I suggested using a for loop and fiddling with the array but then realized there is a native Array.reverse() method.
For curiosity's sake, can anyone help me explore this by showing examples or pointing in the right direction so I can read into this? Any suggestions regarding how to measure performance would be awesome too.
Based on this setup:
var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var length = array.length;
Array.reverse(); is the first or second slowest!
The benchmarks are here:
https://jsperf.com/js-array-reverse-vs-while-loop/9
Across browsers, swap loops are faster. There are two common types of swap algorithms (see Wikipedia), each with two variations.
The two types of swap algorithms are temporary swap and XOR swap.
The two variations handle index calculations differently. The first variation compares the current left index and the right index and then decrements the right index of the array. The second variation compares the current left index and the length divided by half and then recalculates the right index for each iteration.
You may or may not see huge differences between the two variations. For example, in Chrome 18, the first variations of the temporary swap and XOR swap are over 60% slower than the second variations, but in Opera 12, both variations of the temporary swap and XOR swap have similar performance.
Temporary swap:
First variation:
function temporarySwap(array)
{
var left = null;
var right = null;
var length = array.length;
for (left = 0, right = length - 1; left < right; left += 1, right -= 1)
{
var temporary = array[left];
array[left] = array[right];
array[right] = temporary;
}
return array;
}
Second variation:
function temporarySwapHalf(array)
{
var left = null;
var right = null;
var length = array.length;
for (left = 0; left < length / 2; left += 1)
{
right = length - 1 - left;
var temporary = array[left];
array[left] = array[right];
array[right] = temporary;
}
return array;
}
XOR swap:
First variation:
function xorSwap(array)
{
var i = null;
var r = null;
var length = array.length;
for (i = 0, r = length - 1; i < r; i += 1, r -= 1)
{
var left = array[i];
var right = array[r];
left ^= right;
right ^= left;
left ^= right;
array[i] = left;
array[r] = right;
}
return array;
}
Second variation:
function xorSwapHalf(array)
{
var i = null;
var r = null;
var length = array.length;
for (i = 0; i < length / 2; i += 1)
{
r = length - 1 - i;
var left = array[i];
var right = array[r];
left ^= right;
right ^= left;
left ^= right;
array[i] = left;
array[r] = right;
}
return array;
}
There is another swap method called destructuring assignment:
http://wiki.ecmascript.org/doku.php?id=harmony:destructuring
Destructuring assignment:
First variation:
function destructuringSwap(array)
{
var left = null;
var right = null;
var length = array.length;
for (left = 0, right = length - 1; left < right; left += 1, right -= 1)
{
[array[left], array[right]] = [array[right], array[left]];
}
return array;
}
Second variation:
function destructuringSwapHalf(array)
{
var left = null;
var right = null;
var length = array.length;
for (left = 0; left < length / 2; left += 1)
{
right = length - 1 - left;
[array[left], array[right]] = [array[right], array[left]];
}
return array;
}
Right now, an algorithm using destructuring assignment is the slowest of them all. It is even slower than Array.reverse();. However, the algorithms using destructuring assignments and Array.reverse(); methods are the shortest examples, and they look the cleanest. I hope their performance gets better in the future.
Another mention is that modern browsers are improving their performance of array push and splice operations.
In Firefox 10, this for loop algorithm using array push and splice rivals the temporary swap and XOR swap loop algorithms.
for (length -= 2; length > -1; length -= 1)
{
array.push(array[length]);
array.splice(length, 1);
}
However, you should probably stick with the swap loop algorithms until many of the other browsers match or exceed their array push and splice performance.
In simple way you can do this using map.
let list = [10, 20, 30, 60, 90]
let reversedList = list.map((e, i, a)=> a[(a.length -1) -i]) // [90, 60...]
Native methods are always faster.
So use Array.reverse where possible. Otherwise an implementation that runs in O(1) would be best ;)
Otherwise just use something like this
var reverse = function(arr) {
var result = [],
ii = arr.length;
for (var i = ii - 1;i !== 0;i--) {
result.push(arr[i]);
}
return result;
}
Benchmark!
Interesting the loop is faster if you use all three stages of the for construct instead of only one.
for(var i = ii - 1; i !== 0;i--) is faster then var i = ii - 1;for(;i-- !== 0;)
I opened a Firefox bug about slow reverse performance in Firefox. Someone from Mozilla looked at the benchmark used in the accepted post, and says that it is pretty misleading -- in their analysis the native method is better in general for reversing arrays. (As it should be!)
This is the most efficient and clean way to reverse an array with the ternary operator.
function reverse(arr) {
return arr.length < 2 ? arr : [arr.pop()].concat(reverse(arr));
}
console.log(reverse([4, 3, 3, 1]));
Swap functions are the fastest. Here's a reverse function I wrote that is only slightly similar to the swap functions mentioned above but performs faster.
function reverse(array) {
var first = null;
var last = null;
var tmp = null;
var length = array.length;
for (first = 0, last = length - 1; first < length / 2; first++, last--) {
tmp = array[first];
array[first] = array[last];
array[last] = tmp;
}
}
You can find the benchmarking here http://jsperf.com/js-array-reverse-vs-while-loop/19
Since no one came up with it and to complete the list of ways to reverse an array...
array.sort(function() {
return 1;
})
It's twice as fast as both while-approaches, but other than that, horribly slow.
http://jsperf.com/js-array-reverse-vs-while-loop/53
You can do this with .slice().reverse():
const yourArray = ["first", "second", "third", "...", "etc"];
const reversedArray = yourArray.slice().reverse();
console.log(reversedArray);
Note that .slice() is used to prevent modification of yourArray since .reverse() is in-place.
Here's a java example http://www.leepoint.net/notes-java/data/arrays/arrays-ex-reverse.html showing how to reverse an array. Very easy to convert to javascript.
I would suggest using something that simply captures the time before the function is called, and after the function is called. Which ever takes the least time / clock cycles will be the fastest.
Here is another example to permanently modify the array reversing it's elements:
var theArray = ['a', 'b', 'c', 'd', 'e', 'f'];
function reverseArrayInPlace(array) {
for (var i = array.length - 1; i >= 0; i -= 1) {
array.push(array[i]);
}
array.splice(0, array.length / 2);
return array;
};
reverseArrayInPlace(theArray);
console.log(theArray); // -> ["f", "e", "d", "c", "b", "a"]
Another suggestion, similar to the above, but using splice instead:
var myArray=["one","two","three","four","five","six"];
console.log(myArray);
for(i=0;i<myArray.length;i++){
myArray.splice(i,0,myArray.pop(myArray[myArray.length-1]));
}
console.log(myArray);
If you want to copy a reversed version of an array and keep the original as it is:
a = [0,1,2,3,4,5,6,7,8,9];
b = []
for(i=0;i<a.length;i++){
b.push(a.slice(a.length-i-1,a.length-i)[0])
}
Output of b:
[ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
You could also make use of reduceRight which will iterate through each value of the array (from right-to-left)
const myArray = [1, 2, 3, 4, 5]
const reversedArray = myArray.reduceRight((acc, curr) => [...acc, curr], [])
console.log(reversedArray) // [5, 4, 3, 2, 1]
Pasting the below into any javascript runtime console either on the browser or node.js would do a straight way benchmark test on a large array of number.
Say 40,000 in my case
var array = Array.from({ length: 40000 }, () =>
Math.floor(Math.random() * 40000)
);
var beforeStart = Date.now();
var reversedArray = array.map((obj, index, passedArray) => {
return passedArray[passedArray.length - index - 1];
});
console.log(reversedArray);
var afterCustom = Date.now();
console.log(array.reverse());
var afterNative = Date.now();
console.log(`custom took : ${afterCustom - beforeStart}ms`);
console.log(`native took : ${afterNative - afterCustom}ms`);
You can simply run the snippet directly to see how the custom version fare too.
For the sake of completeness there should be also thought about efficiency in a broader way, than only execution-time performance.
Therefore I'd like to add a swap function that is minimal slower (please test on your own using perf tools) than than the ones from the accepted answer but it has the following other beneficial properties:
it doesn't require a temp variable for swapping
it keeps the input array untouched
it works also with arrays of values other than numerical because it simply swaps references
it does not start a function call on every iteration step
it keeps being readable (although this could still be improved)
function fastSwapReverse (array) {
// half length for odd arrays is added by 1
var len = array.length;
var half = len % 2 === 0 ? len / 2 : Math.ceil(len / 2)
var k = 0, A = new Array(len)
// from 0 to half swap the elements at
// start: 0 + i
// end: len - i -1
for (k = 0; k < half; k++) {
A[k] = array[len - k - 1];
A[len - k - 1] = array[k];
}
return A;
}
Although the original Array.prototype.reverse method also does mutate the array
Just start copying array from the backside using a for loop and return that new array. This is efficient and has O(n) time complexity.
var array1 = ["yes", "no", "maybe", "always", "sometimes", "never", "if"];
var array2 = [5,8,2,9,5,6,3,1];
function reverseArray(arr) {
var newArray = [];
for (var x = arr.length - 1; 0 <= x; --x) {
newArray.push(arr[x]);
}
return newArray;
}
console.log(reverseArray(array1)); // ["if", "never", "sometimes", "always", "maybe", "no", "yes"]
console.log(reverseArray(array2)) // [1, 3, 6, 5, 9, 2, 8, 5]
Here are a couple of tricks I found. Credit goes to Codemanx for the original solution of
array.sort(function() {
return 1;
})
In Typescript, this can be simplified to just one line
array.sort(() => 1)
var numbers = [1,4,9,13,16];
console.log(numbers.sort(() => 1));
Since this will be the future of JavaScript, I thought I'd share that.
Here's another trick if your array only has 2 elements
array.push(array.shift());
// array-reverse-polyfill.js v1
Array.prototype.reverse = Array.prototype.reverse || function() {
return this.sort(function() {
return -1;
});
};
If you are in a modern browser you use the native reverse function. If it's not modern this polyfill will add this function for you. So just use it:
I haven't found any cases where Firefox does the opposite behavior to other browsers. Anyway, if you want to ensure that the function will sort alphabetically, just do a little test first.
// array-reverse-polyfill.js v1.1
;(function(){
var order = ['a', 'b'].sort(function(a, b){
return -1;
});
order = order[0] === 'b' ? -1 : 1;
Array.prototype.reverse = Array.prototype.reverse || function() {
return this.sort(function() {
return order;
});
};
})();
Example of use:
let a = [1,2,3,4,5];
a.reverse();
console.log(a);
I am new to javaScript and struggle a bit with looping and writing functions. I am trying to come up with a function that cycles through my rangeArray where the users inputted number is the end of the array, and each integer that includes 1 is replaced with "Beep" up to that users inputted number. Ex: [ 0, "Beep", 2, 3, 4, 5, 6, 7, 8, 9, "Beep", "Beep", 12 ]. 12 and 2 will be different because later I intend on adding an exception where if a number includes any integer of 2, it supersedes the "Beep" and will replace it with "Boop". Does anyone have any idea how this function would be written? So far I've attempted writing a .includes or even using splice but so far I have only been able to replace the number 1 and nothing else. Help would be much appreciated! Thank you :)
Here is my code so far:
function convertToNumber(input) {
let parsedInput = parseInt(input);
console.log(input);
if (!isNaN(parsedInput)) {
return parsedInput;
} else {
return false;
}
}
function rangeOfNumbers(start,end) {
let rangeArray = [];
for (let i = start; i <= end; i++) {
rangeArray.push(i + " ");
}
if (rangeArray); {
rangeArray.forEach (function (number) {
rangeArray.splice(1,'1',"Beep");
}); return rangeArray;
};
}
console.log(rangeOfNumbers(0,12));
To create a new array, use Array.prototype.map with RegExp.prototype.test to cast integers to string and test for a specific value is contained:
const beepify = arr => arr.map(v => (
/2/.test(v) ? "Boop" :
/1/.test(v) ? "Beep" :
v));
console.log(beepify([0,1,2,3,4,5,6,7,8,9,10,11,12]));
Read also about Ternary Operator which is used above in a superceding manner as desired.
You can use Array#map.
function rangeOfNumbers(start,end) {
let rangeArray = [];
for (let i = start; i <= end; i++) {
rangeArray.push(i + "");
}
return rangeArray.map(x => x.includes("2") ? "Boop" : x.includes("1") ? "Beep" : x);
}
console.log(rangeOfNumbers(0,12).join());
Array.from can also be used.
function rangeOfNumbers(start,end) {
return Array.from({length:end-start+1},
(_,i)=>(i+start+"").includes("1") ? "Beep": i + start);
}
console.log(rangeOfNumbers(0,12).join());
I am completing the hackerrank's 10 days of javascript challenge. The question:
write a function to take an array as an argument and then return the second largest element in the array.
I have written the code but my code is returning the largest element and not the second largest as asked.
function getSecondLargest(nums) {
// Complete the function
var largest=nums[0];
for(let i=1;i<nums.length;++i)
{
if(nums[i]>largest)
largest=nums[i];
}
var large=nums[0];
for(let j=1;j<nums.length;++j)
{
if(large<nums[j]&&large<largest)
large=nums[j];
}
return large;
}
When input array nums={2,3,6,6,5} the result is coming 6 while expected output is 5. Please help and point out the errors in the function code below.
should not initialize large with first value var large=nums[0]; because it may appear the biggest value and won't work
should use nums[j]<largest instead of large<largest as mentioned above
I think don't need second loop as all checks can be done in first loop, and you can assign prev largest to large whenever you change it:
function getSecondLargest(nums) {
var largest = nums[0];
var large;
for (let i = 1; i < nums.length; ++i) {
if (nums[i] > largest) {
large = largest;
largest = nums[i];
} else if (nums[i] > large || typeof large === 'undefined') {
large = nums[i]
}
}
return large;
}
console.log(getSecondLargest([5,1-2,3]))
console.log(getSecondLargest([-5,1,-2,3]))
GET SECOND LARGEST
first, I create new array with unique values.
let arr = [...new Set(nums)];
second, sort value using built-in function .sort().
note : by default .sort() always sorts asciibetically, but for some testcase, it doesn't work. So, I put (a, b) => { return a - b } to make sure it will work properly.
arr = arr.sort((a, b) => { return a -b });
third, get the value from arr
let result = arr[arr.length - 2] || arr[0];
finally, return the result
return result
function getSecondLargest(nums) {
let arr = [...new Set(nums)];
//Javascript's array member method .sort( always sorts asciibetically.
arr = arr.sort((a, b) => { return a - b });
let result = arr[arr.length - 2] || arr[0];
return result
}
Just one minor change:
Use nums[j]<largest instead of large<largest in the second for loop
function getSecondLargest(nums) {
// Complete the function
var largest=nums[0];
for(let i=1;i<nums.length;++i)
{
if(nums[i]>largest)
largest=nums[i];
}
var large;
//To ensure that the selected number is not the largest
for(let j=0;j<nums.length;++j)
{
if (nums[j] !== largest){
large = nums[j];
break;
}
}
for(let j=1;j<nums.length;++j)
{
if(large<nums[j]&&nums[j]!=largest)
large=nums[j];
else
console.log(large)
}
return large;
}
var secondLargest = getSecondLargest([6,3,6,6,5]);
console.log("Second largest number", secondLargest);
If you want to avoid using library functions like #ifaruki suggests, this line
if(large<nums[j]&&large<largest)
should read
if (large<nums[j] && nums[j] < largest)
Sorting and picking the second or second-to-last value fails when there are duplicates of the highest value in the input array.
Another easiest logic is to remove duplicates from the array and sort.
let givenArray = [2, 3, 6, 6, 5];
let uniqueArray = [...new Set(givenArray)];
console.log("The second largets element is", uniqueArray.sort()[uniqueArray.length - 2]);
I know you had your question answered, just thought I would provide my solution for any future users looking into this.
You can use reduce to go through the array while remembering the two largest numbers so far.
You just make a simple reduction function:
function twoMax(two_max, candidate)
{
if (candidate > two_max[0]) return [candidate,two_max[0]];
else if (candidate > two_max[1]) return [two_max[0],candidate];
else return two_max;
}
And then you use it for example like this:
let my_array = [0,1,5,7,0,8,12];
let two_largest = my_array.reduce(twoMax,[-Infinity,-Infinity]);
let second_largest = two_largest[1];
This solution doesn't require sorting and goes through the array only once.
If you want to avoid using **sort method. I think here's the easiest logic to do that, which will also work in arrays where there's duplicates of largest integer exists.
function getSecondLargest(arr) {
const largest = Math.max.apply(null, arr);
for (let i = 0; i < arr.length; i++) {
if (largest === arr[i]) {
arr[i] = -Infinity;
}
}
return Math.max.apply(null, arr);
}
console.log(getSecondLargest([5, 7, 11, 11, 11])); //7
I'm studing a solution of this lesson:
https://app.codility.com/programmers/lessons/4-counting_elements/perm_check/
I headed up of this solution made my a github user.
https://github.com/daraosn/codility/tree/master/02-CountingElements/02-PermCheck/javascript
I did understand everything of the code below:
function solution(A) {
var N = A.length;
var sum = (N * (N+1)) / 2;
var tap = [];
for (var i in A) {
sum-=A[i];
if(tap[A[i]]) {
return 0;
}
tap[A[i]] = true;
}
return +(sum==0);
}
with exception of these code lines below:
if(tap[A[i]]) {
return 0;
}
tap[A[i]] = true;
What is its purppose? I didn't understand.
I did a test deleting these code lines from the answer in the
codility interface and it returned 75% right instead of 100% when I had these lines
function solution(A) {
const set = new Set(A)
const max = Math.max(...A)
return set.size === max && set.size === A.length ? 1:0
}
That section checks to see if the number being iterated over has been found before, and per the instructions, duplicates are forbidden:
A permutation is a sequence containing each element from 1 to N once, and only once.
On every normal iteration, the current number being iterated over is assigned to a property of tap:
tap[A[i]] = true;
Then, on subsequent iterations, that test checks to see if the new number being iterated over has already been used:
if(tap[A[i]]) {
return 0;
}
This helps to invalidate inputs like [2, 2, 2], while permitting inputs like [1, 2, 3].
That said, there are two major red flags with this. First, for..in shouldn't be used to iterate over arrays. Instead:
for (const num of A) {
// use num
}
Also, sparse arrays are a very bad idea - it would make much more sense to use an object:
var tap = {};
or a Set:
var tap = new Set();
for (const num of A) {
sum -= num;
if (tap.has(num)) {
return 0;
}
tap.add(num);
}
return +(sum == 0);
Array solution is not so proper way such above explaining. But I will put the solution(O(n)) in case you want :)
const solution = A => ~~(A.sort((a,b) => a-b).every((a,i) => a === i+1));
For some reason I'm having some serious difficulty wrapping my mind around this problem. I need this JS function that accepts 2 arrays, compares the 2, and then returns a string of the missing element. E.g. Find the element that is missing in the currentArray that was there in the previous array.
function findDeselectedItem(CurrentArray, PreviousArray){
var CurrentArrSize = CurrentArray.length;
var PrevousArrSize = PreviousArray.length;
// Then my brain gives up on me...
// I assume you have to use for-loops, but how do you compare them??
return missingElement;
}
Thank in advance! I'm not asking for code, but even just a push in the right direction or a hint might help...
Problem statement:
Find the element that is missing in the currentArray that was there in the previous array.
previousArray.filter(function(x) { // return elements in previousArray matching...
return !currentArray.includes(x); // "this element doesn't exist in currentArray"
})
(This is as bad as writing two nested for-loops, i.e. O(N2) time*). This can be made more efficient if necessary, by creating a temporary object out of currentArray, and using it as a hashtable for O(1) queries. For example:)
var inCurrent={}; currentArray.forEach(function(x){ inCurrent[x]=true });
So then we have a temporary lookup table, e.g.
previousArray = [1,2,3]
currentArray = [2,3];
inCurrent == {2:true, 3:true};
Then the function doesn't need to repeatedly search the currentArray every time which would be an O(N) substep; it can instantly check whether it's in currentArray in O(1) time. Since .filter is called N times, this results in an O(N) rather than O(N2) total time:
previousArray.filter(function(x) {
return !inCurrent[x]
})
Alternatively, here it is for-loop style:
var inCurrent = {};
var removedElements = []
for(let x of currentArray)
inCurrent[x] = true;
for(let x of previousArray)
if(!inCurrent[x])
removedElements.push(x)
//break; // alternatively just break if exactly one missing element
console.log(`the missing elements are ${removedElements}`)
Or just use modern data structures, which make the code much more obvious:
var currentSet = new Set(currentArray);
return previousArray.filter(x => !currentSet.has(x))
*(sidenote: or technically, as I illustrate here in the more general case where >1 element is deselected, O(M*N) time)
This should work. You should also consider the case where the elements of the arrays are actually arrays too. The indexOf might not work as expected then.
function findDeselectedItem(CurrentArray, PreviousArray) {
var CurrentArrSize = CurrentArray.length;
var PreviousArrSize = PreviousArray.length;
// loop through previous array
for(var j = 0; j < PreviousArrSize; j++) {
// look for same thing in new array
if (CurrentArray.indexOf(PreviousArray[j]) == -1)
return PreviousArray[j];
}
return null;
}
Take a look at underscore difference function: http://documentcloud.github.com/underscore/#difference
I know this is code but try to see the difference examples to understand the way:
var current = [1, 2, 3, 4],
prev = [1, 2, 4],
isMatch = false,
missing = null;
var i = 0, y = 0,
lenC = current.length,
lenP = prev.length;
for ( ; i < lenC; i++ ) {
isMatch = false;
for ( y = 0; y < lenP; y++ ) {
if (current[i] == prev[y]) isMatch = true;
}
if ( !isMatch ) missing = current[i]; // Current[i] isn't in prev
}
alert(missing);
Or using ECMAScript 5 indexOf:
var current = [1, 2, 3, 4],
prev = [1, 2, 4],
missing = null;
var i = 0,
lenC = current.length;
for ( ; i < lenC; i++ ) {
if ( prev.indexOf(current[i]) == -1 ) missing = current[i]; // Current[i] isn't in prev
}
alert(missing);
And with while
var current = [1, 2, 3, 4],
prev = [1, 2, 4],
missing = null,
i = current.length;
while(i) {
missing = ( ~prev.indexOf(current[--i]) ) ? missing : current[i];
}
alert(missing);
This is my approach(works for duplicate entries too):-
//here 2nd argument is actually the current array
function(previousArray, currentArray) {
var hashtable=[];
//store occurances of elements in 2nd array in hashtable
for(var i in currentArray){
if(hashtable[currentArray[i]]){
hashtable[currentArray[i]]+=1; //add 1 for duplicate letters
}else{
hashtable[currentArray[i]]=1; //if not present in hashtable assign 1
}
}
for(var i in previousArray){
if(hashtable[previousArray[i]]===0 || hashtable[previousArray[i]] === undefined){ //if entry is 0 or undefined(means element not present)
return previousArray[i]; //returning the missing element
}
else{
hashtable[previousArray[i]]-=1; //reduce count by 1
}
}
}
Logic is that i have created a blank array called hashtable. We iterate currentArray first and use the elements as index and values as counts starting from 1(this helps in situations when there are duplicate entries). Then we iterate through previousArray and look for indexes, if they match we reduce the value count by 1. If an element of 2nd array doesnt exist at all then our undefined check condition fires and we return it. If duplicates exists, they are decremented by 1 each time and when 0 is encountered, that elment is returned as missing element.