Python to Javascript - javascript

>>> def clockwise(r):
... return list(r[0]) + clockwise(list(reversed(zip(*r[1:])))) if r else []
...
>>> a = [
... [ 1, 2, 3],
... [ 5, 6, 7],
... [ 9, 10, 11]]
>>> clockwise(a)
[1, 2, 3, 7, 11, 10, 9, 5, 6]
I'm trying to change the function clockwise into Javascript but can't seem to get it to work.
I've created some methods with similar functions:
function zip(masterArray){//zips 2 arrays
var innerLoop = masterArray.length; //inner loop
var outerLoop = 0;
//get length of shortest
for (var i = 0; i<masterArray.length;i++){
var a = masterArray[i].length;
if (outerLoop==0){outerLoop = a;}else if(a < outerLoop){outerLoop = a;}
}
var newOuterArray = new Array(outerLoop);
for (var x = 0; x<outerLoop;x++){
var newInnerArray = new Array(innerLoop);
for (var y = 0; y<innerLoop;y++){
newInnerArray[y] = masterArray[y][x];
}
newOuterArray[x] = newInnerArray;
}
return newOuterArray;
}
function reversed(arr){
var newArray = new Array(arr.length);
var n = 0;
for(var i=arr.length-1; i>=0; i--){
newArray[n++] = arr[i];
}
return newArray;
}
function clockwise(r){
if(r.length>0){
var a = reversed(zip(r.slice(1)));
a.splice(0,0,r[0]);
return clockwise(a);
}else{
return [];
}
}
Here's my progress. I'm stuck at the last part: clockwise error in firebug is too much recursion.

I think the problem lies in the use of splice. Try something like this instead...
function clockwise(r){
if(r.length>0){
var remaining = r.slice(1)
var a = reversed(zip(remaining));
return r[0].concat(clockwise(a));
} else {
return [];
}
}

I think you want the recursive call to clockwise() to be before you prepend r[0] otherwise you never get down to an empty string.

I don't follow what the algorithm is trying to do, but the Javascript version of clockwise looks like it can only ever return []. There are two return paths. One calls clockwise, the other returns [] so the only way out of that function is to return []. That's not how your python version works.
I haven't looked at reversed and zip, but there is a logic difference in the javascript version of clockwise. In the javascript version, you remove the first item in the array, then reverse and zip, then put the first item back on the array and call clockwise on the whole thing. In the Python version, you remvoe the first item in the array, call clocks and reverse on only the item without the first version, then add the first one back on afterwards. Very different logic. The Python version is much more likely to end.
I haven't looked at the other functions reverse and zip, but this looks like a more faithful javascript version of clockwise:
function clockwise(r) {
if (r.length > 0) {
var a = clockwise(reversed(zip(r.slice(1)))); // call clockwise on array starting at index 1
a.splice(0,0,r[0]); // put first value in original array back onto the beginning of the result
return (a); // return new array
} else {
return [];
}
}

Related

How to make reverse array work with for loop only [duplicate]

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);

JS - Lesson on codility involving perm check

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));

how to increment interger array by 1

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]))

JavaScript Variables Not Defining Correctly Inside Function

I'm new to JS and am trying to create a simple 'swap array elements if array A element is bigger than array B element' function. In the swapIndexes function, I don't understand why I can't define the variables as shown in the comments. For example, it works if it state arrA[c] rather than let a = arrA[c].
Why does this happen? Can anyone give some beginner tips on how best to go about something like this? My code feels verbose. Thanks for any help here.
var arrA = [0, 1, 2, 7, 6],
arrB = [0, 1, 2, 5, 7],
indexesToSwap = [],
aValuesToSwap = [],
bValuesToSwap = [],
needSwapping = false;
arrA.forEach(getSwappableIndexesAndValues);
indexesToSwap.forEach(swapIndexes);
function getSwappableIndexesAndValues(c, i) {
let b = arrB[i];
if (c > b) {
needSwapping = true;
indexesToSwap.push(i);
aValuesToSwap.push(b);
bValuesToSwap.push(c);
}
}
function swapIndexes(c, i) {
//let a = arrA[c]; fails why???
//let b = arrB[c]; fails why???
//a = aValuesToSwap[i]; fails why???
//b = bValuesToSwap[i]; fails why???
arrA[c] = aValuesToSwap[i];
arrB[c] = bValuesToSwap[i];
}
console.log(arrA);
console.log(arrB);
In javascript, when you create a variable from a given index in an array, This will create a new memory space containing a copy of the value at this index. The newly created variable will not point to the content of the array and thus, modifying this variable will not modify the content of the array.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
indexesToSwap has all the information you need to swap. The swap value arrays (aValuesToSwap, bValuesToSwap) are greatly complicating matters and are wholly unnecessary.
Regardless of the values to swap arrays, swapping is a fundamental operation and typically involves a simple temporary, e.g.
temp = arrA[i];
arrA[i] = arrB[i];
arrB[i] = temp;
Discarding the complexities, here's an alternative to the function getSwappableIndexesAndValues
function getSwappableIndexes(c, i) {
if (c > arrB[i])
indexesToSwap.push(i);
}
And a simplified swap function
function swapIndexes(c, i) {
let temp = arrA[c];
arrA[c] = arrB[c];
arrB[c] = temp;
}
I have to say further though that the use of Array.forEach wildly complicates the entire solution. Unless this is an assignment, using a simple for-loop is best here.
// swaps values between arrays where the value in
// array a is greater than the value in array b
//
function swapIfGreaterThan(a,b) {
for(let i = 0; i < a.length && i < b.length; i++) {
if(a[i] > b[i]) {
let temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}
}
var arrA = [0, 1, 2, 7, 6],
arrB = [0, 1, 2, 5, 7],
indexesToSwap = [],
aValuesToSwap = [],
bValuesToSwap = [],
needSwapping = false;
arrA.forEach(getSwappableIndexesAndValues);
indexesToSwap.forEach(swapIndexes);
function getSwappableIndexesAndValues(c, i) {
let b = arrB[i];
if (c > b) {
needSwapping = true;
indexesToSwap.push(i);
aValuesToSwap.push(b);
bValuesToSwap.push(c);
}
}
function swapIndexes(c, i) {
//let a = arrA[c]; fails why???
//let b = arrB[c]; fails why???
//a = aValuesToSwap[i]; fails why???
//b = bValuesToSwap[i]; fails why???
arrA[c] = bValuesToSwap[i];
arrB[c] =aValuesToSwap[i];
console.log( arrA[c], arrB[c]);
console.log( aValuesToSwap[i], bValuesToSwap[i]);
}
console.log(arrA);
console.log(arrB);
It is not possible array values and primitive data type values are different. If you try with the array of the object your attempt will be correct.

Find missing element by comparing 2 arrays in Javascript

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.

Categories