Issue with custom array ordering sequence Javascript - javascript

I am facing an issue with array ordering sequence. Need your help for desired result.
var a = [0, 1, 2, 3, 4, 5, 6, 77, 7, 8, 9, 10, 11, 12, 35, 36, 43, 51, 72, 89, 95, 100];
var b = [6,5,7,8,0,800,46,1,2,3,12,47,100,95];
var c = [];
for (var i = 0; i <= (a.length) - 1; i++) {
var res = b.indexOf(a[i]);
if (res > -1) {
c.push(a[i]);
}
}
document.write(c);
// I need same sequence of array B in reponse
// Desired Result
// 6,5,7,8,0,1,2,3,12,100,95

Iterate array b instead of a:
var a = [0, 1, 2, 3, 4, 5, 6, 77, 7, 8, 9, 10, 11, 12, 35, 36, 43, 51, 72, 89, 95, 100];
var b = [6,5,7,8,0,800,46,1,2,3,12,47,100,95];
var c = [];
for (var i = 0; i < b.length; i++) {
var res = a.indexOf(b[i]);
if (res > -1) {
c.push(b[i]);
}
}
console.log(c.join(','));
A more functional solution is to use Array#filter on b:
var a = [0, 1, 2, 3, 4, 5, 6, 77, 7, 8, 9, 10, 11, 12, 35, 36, 43, 51, 72, 89, 95, 100];
var b = [6,5,7,8,0,800,46,1,2,3,12,47,100,95];
var c = b.filter(function(n) {
return a.indexOf(n) !== -1;
});
console.log(c.join(','));

Related

How do I replace unique values from another array, by replacing the original array

So I have two sets of Array, one of them is an object (arrA). And another one is just a set of primitive values arrB.
let a = "100229265852737908723455202093346882084130103685642861644052656467061936958706";
let arrA = [];
let arrB = [];
for (let i = 1; i <= 28; i++) {
arrA.push({index: i, pos: i, unique: false});
arrB.push(i);
}
let b = a.split(/(?=(?:..)*$)/).slice(0, 28);
b.forEach((val, index) => {
let c = Math.floor((+val / 100) * 28 ) + 1;
if (arrB.indexOf(c) !== -1) {
arrB.splice(arrB.indexOf(c), 1);
arrA[index].unique = true;
}
arrA[index].pos = c;
});
arrB.forEach((val, index) => {
arrA.forEach((valA, indexA) => {
if (!valA.unique) {
if (arrB[index] > valA.pos) {
arrA[indexA].pos = arrB[index];
arrA[indexA].unique = true;
arrB.splice(arrB.indexOf(arrB[index]));
}
}
})
});
My expected result is, arrA.pos is:
3, 1, 9, 8, 17, 15, 21, 4, 22, 10, 16, 6, 7, 27, 13, 20, 25, 5, 12, 14, 19, 11, 24, 18, 26, 28, 2
 
However I got:
3, 1, 9, 8, 17, 15, 21, 4, 21, 10, 16, 6, 6, 27, 10, 20, 23, 3, 12, 9, 3, 11, 24, 18, 8, 18, 18
If your goal is to take the string, split it into an array of elements of an arbitrary length, each being a 2-digit number, then output an Array that contains only the original Array's unique values, then you can do this:
const MAGIC_NUMBER = 28;
const a = "100229265852737908723455202093346882084130103685642861644052656467061936958706";
const b = a.split(/(?=(?:..)*$)/).slice(0, MAGIC_NUMBER );
const unique = Array.from( new Set( b ));
Set at MDN

How to implement insertion sort for two arrays in ES6

Let's say that I have two arrays:
arr1 - [90, 44, 64, 16, 24, 20, 64, 86, 20, 64, 56, 72, 16]
and
arr2 - [21, 13, 9, 13, 15, 7, 17, 15, 9, 19, 7, 15, 9]
I want to implement insertion sort for two arrays and receive the sorted result array:
[
90, 86, 72, 64, 64, 64, 56, 44,
24, 21, 20, 20, 19, 17, 16, 16,
15, 15, 15, 13, 13, 9, 9, 9,
7, 7
]
I know that I can achieve it indirectly with:
resultArray = arr1.concat(arr2).sort(function(a, b) {return b - a});
but it's not the best solution when it comes to performance.
I will be grateful for suggestions on how to achieve the above assumption with ES6 usage.
Use spread operator to concatenate, then arrow function to sort:
let arr1 = [90, 44, 64, 16, 24, 20, 64, 86, 20, 64, 56, 72, 16];
let arr2 = [21, 13, 9, 13, 15, 7, 17, 15, 9, 19, 7, 15, 9];
let resultArray = [...arr1, ...arr2].sort((a, b) => b - a);
console.log("arr1:");
console.log("["+arr1.join(", ")+"]");
console.log("arr2:");
console.log("["+arr2.join(", ")+"]");
console.log("resultArray:");
console.log("["+resultArray.join(", ")+"]");
.as-console-wrapper { max-height: 100% !important; top: 0; }
Testing for larger Arrays:
let arr1 = [90, 44, 64, 16, 24, 20, 64, 86, 20, 64, 56, 72, 16];
let arr2 = [21, 13, 9, 13, 15, 7, 17, 15, 9, 19, 7, 15, 9];
for(let i=0; i<10; i++) {
arr1 = arr1.concat(arr1);
arr2 = arr2.concat(arr2);
};
let start = null;
let resultArray = null;
start=new Date();
resultArray = [...arr1, ...arr2].sort((a, b) => b - a);
console.log("First resultArray took " + (Date.now() - start) + "ms");
start = null;
resultArray = null;
start=new Date();
resultArray = arr1.concat(arr2).sort(function(a, b) {return b - a});
console.log("Second resultArray took " + (Date.now() - start) + "ms");
.as-console-wrapper { max-height: 100% !important; top: 0; }
Seems like let resultArray = [...arr1, ...arr2].sort((a, b) => b - a); takes longer than what resultArray = arr1.concat(arr2).sort(function(a, b) {return b - a}); takes...
You can sort the arrays separately then merge them:
const sarr1 = arr1.sort((a, b) => b - a);
const sarr2 = arr2.sort((a, b) => b - a);
const tot = [];
let arr1i = 0;
let arr2i = 0;
while (arr1i < sarr1.length && arr2i < sarr2.length) {
if (sarr1[arr1i] >= sarr2[arr2i]) {
tot.push(sarr1[arr1i]);
arr1i++;
} else {
tot.push(sarr2[arr2i]);
arr2i++;
}
}
while (arr1i < sarr1.length) {
tot.push(sarr1[arr1i ++]);
}
while (arr2i < sarr2.length) {
tot.push(sarr2[arr2i ++]);
}
// tot now contains the fully sorted array

How does this for in Loop Work to Sort Numbers using Quick Sort in JavaScript

How does the for in loop work below to correctly sort the numbers in the left array and right array for the quick sort implementation below?
I'd like an example of a first example iteration of the sortArr(left) recursive call, then another iteration, and so on (maybe up to three or four iterations).
Then I'll be able to understand the sortArr(left), including the sortArr(right) recursive call.
const unsortedArr = [31, 27, 28, 42, 13, 8, 11, 30, 17, 41, 15, 43, 1, 36, 9, 16, 20, 35, 48, 37, 7, 26, 34, 21, 22, 6, 29, 32, 49, 10, 12, 19, 24, 38, 5, 14, 44, 40, 3, 50, 46, 25, 18, 33, 47, 4, 45, 39, 23, 2];
let sortArr = (arr) => {
if (arr.length < 2) return arr;
const pivot = arr[Math.floor(arr.length / 2)];
let left = [];
let equal = [];
let right = [];
equal.push(pivot);
for (let element of arr) {
if (element < pivot) {
left.push(element);
} else if (element > pivot) {
right.push(element);
}
}
let sortedArr = sortArr(left)
.concat(equal)
.concat(sortArr(right));
return sortedArr;
};
console.log(sortArr(unsortedArr));

Spiral Matrix: Inner Functions Work But Throw Error When Used In While Loop

A Spiral Matrix coding challenge in JavaScript; of particular importance are the four inner functions leftToRight, topToBottom, rightToLeft, and bottomToTop. Commenting out the while loop and invoking the four functions within the scope of spiralCopy like so:
leftToRight(iLeftRightStart, iLeftRightEnd, leftRightPosition);
topToBottom(iTopBottomStart, iTopBottomEnd, topBottomPosition);
rightToLeft(iRightLeftStart, iRightLeftEnd, rightLeftPosition);
bottomToTop(iBottomTopStart, iBottomTopEnd, bottomTopPosition);
Returns [ 1, 2, 3, 4, 5, 6, 12, 18, 24, 30, 36, 35, 34, 33, 32, 31, 25, 19, 13, 7 ], as expected.
However, when used in the while loop in the code below the program crashes with the following error:
spiral.push(matrix[position][i]);
^
TypeError: Cannot read property '1' of undefined
Here is the entire program:
inputMatrix = [
[1, 2, 3, 4, 5, 6],
[7, 8, 9, 10, 11, 12],
[13, 14, 15, 16, 17, 18],
[19, 20, 21, 22, 23, 24],
[25, 26, 27, 28, 29, 30],
[31, 32, 33, 34, 35, 36]
]
const spiralCopy = (matrix) => {
const spiralLength = matrix.length * matrix[0].length;
const spiral = [];
let iLeftRightStart = 0; // +1
let iLeftRightEnd = matrix[0].length; // -1
let leftRightPosition = 0; // +1
let iTopBottomStart = 1; // +1
let iTopBottomEnd = matrix.length; // -1
let topBottomPosition = matrix[0].length - 1; // -1
let iRightLeftStart = matrix[0].length - 2; // -1
let iRightLeftEnd = 0; // +1
let rightLeftPosition = matrix.length - 1; // -1
let iBottomTopStart = matrix.length - 2; // -1
let iBottomTopEnd = 1; // +1
let bottomTopPosition = 0; // +1
const leftToRight = (iStart, iEnd, position) => {
console.log(iStart, iEnd, position);
for (let i = iStart; i < iEnd; i++) {
spiral.push(matrix[position][i]);
}
}
const topToBottom = (iStart, iEnd, position) => {
for (let i = iStart; i < iEnd; i++) {
spiral.push(matrix[i][position]);
}
}
const rightToLeft = (iStart, iEnd, position) => {
for (let i = iStart; i >= iEnd; i--) {
spiral.push(matrix[position][i]);
}
}
const bottomToTop = (iStart, iEnd, position) => {
for (let i = iStart; i >= iEnd; i--) {
spiral.push(matrix[i][position]);
}
}
while (spiral.length < spiralLength) {
leftToRight(iLeftRightStart, iLeftRightEnd, leftRightPosition);
topToBottom(iTopBottomStart, iTopBottomEnd, topBottomPosition);
rightToLeft(iRightLeftStart, iRightLeftEnd, rightLeftPosition);
bottomToTop(iBottomTopStart, iBottomTopEnd, bottomTopPosition);
iLeftRightStart++;
iLeftRightEnd--;
leftRightPosition--;
iTopBottomStart++;
iTopBottomEnd--;
topBottomPosition--;
iRightLeftStart--;
iRightLeftEnd++;
rightLeftPosition--;
iBottomTopStart--;
iBottomTopEnd++;
bottomTopPosition++;
}
return spiral;
}
console.log(spiralCopy(inputMatrix));
// should print [1, 2, 3, 4, 5, 6, 12, 18, 24, 30, 36, 35, 34, 33, 32, 31, 25, 19, 13, 7, 8, 9, 10, 11, 17, 23, 29, 28, 27, 26, 20, 14, 15, 16, 22, 21]
Why are the functions not working in the while loop?
The problem was decrementing leftRightPosition instead of incrementing it.
I changed the
leftRightPosition--;
To
leftRightPosition++;
And it works.

How to Test Random Output?

The code below is used to play a Lottery game.
let Lotto = {
_nMap: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50
],
_sMap: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
],
/**
* #param {Array} shuffleArr
*
* #return {Array}
*/
_shuffleArr(shuffleArr) {
let rndNr, tmpValue;
for (let elmNr = shuffleArr.length - 1; elmNr > 0; elmNr--) {
rndNr = Math.floor(
Math.random() * (elmNr + 1)
);
tmpValue = shuffleArr[rndNr];
shuffleArr[rndNr] = shuffleArr[elmNr];
shuffleArr[elmNr] = tmpValue;
}
return shuffleArr;
},
/**
* #return {Object}
*/
getPick() {
return {
n: this._shuffleArr(this._nMap).slice(0, 5),
s: this._shuffleArr(this._sMap).slice(0, 2)
}
}
};
Now I want to verify whether the implementation is correct. For example: it should return a unique set of numbers. How do I test this? Run the .getPick() method once and validate the output or ...?
You can write a test case like, getting the script to run 10 to 15 times, and putting the values inside an array and finding the pattern. Something like this would be nice:
let Lotto = {
_nMap: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50
],
_sMap: [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
],
/**
* #param {Array} shuffleArr
*
* #return {Array}
*/
_shuffleArr(shuffleArr) {
let rndNr, tmpValue;
for (let elmNr = shuffleArr.length - 1; elmNr > 0; elmNr--) {
rndNr = Math.floor(
Math.random() * (elmNr + 1)
);
tmpValue = shuffleArr[rndNr];
shuffleArr[rndNr] = shuffleArr[elmNr];
shuffleArr[elmNr] = tmpValue;
}
return shuffleArr;
},
/**
* #return {Object}
*/
getPick() {
return {
n: this._shuffleArr(this._nMap).slice(0, 5),
s: this._shuffleArr(this._sMap).slice(0, 2)
}
}
};
var entries = [];
for (var i = 0; i < 100; i++)
entries.push(JSON.stringify(Lotto.getPick()));
var counts = {};
for (var i = 0; i < entries.length; i++) {
counts[entries[i]] = 1 + (counts[entries[i]] || 0);
}
console.log(counts);
if (Object.keys(counts).length == 100)
alert("Excellent, 0 dupes!");
else if (Object.keys(counts).length > 75)
alert("More than 75% unique.");
else
alert("Less than 75% unique.");
Here, I could find every output is a distinct one. That's how you need to automate or write test cases. The above snippet itself is a testing solution. Try it out and let me know if it works out for you.

Categories

Resources