Get the intersection of three arrays in JavaScript - javascript

I need to make a utility that checks the intersection of 3 arrays.
Here's my implementation in JS:
function intersection(array1, array2, array3) {
let intermediateList = [];
let intermediateList2 = [];
for (let i = 0; i < array1.length; i++) {
if (!(array2.indexOf(array1[i]) == -1)) {
intermediateList.push(array1[i]);
}
for (let j = 0; j < intermediateList.length; j++) {
if (!(intermediateList.indexOf(array3[j]) == -1)) {
intermediateList2.push(intermediateList[i]);
}
}
}
let endList = [ ...intermediateList, ...intermediateList2];
return endList;
}
intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20])
//  [5, 15] /--> fine
intersection([5, 10, 15, 20, 40, 32], [32, 15, 88, 1, 5, 7, 40], [1, 10, 15, 5, 20, 40, 32])
// [5, 15, 40, 32, undefined, undefined, undefined] /--> can someone spot why do I get those undefined values?
How would you implement this with reduce?

Your function has a nested for loop which iterates the intermediateList every time where the outer loop is running. Then you push a value with index i instead of index j, but this should work only if the two for loops are not nested but chained.
function intersection(array1, array2, array3) {
let intermediateList = [];
let intermediateList2 = [];
for (let i = 0; i < array1.length; i++) {
if (array2.indexOf(array1[i]) !== -1) {
intermediateList.push(array1[i]);
}
}
for (let j = 0; j < intermediateList.length; j++) {
if (array3.indexOf(intermediateList[j]) !== -1) {
intermediateList2.push(intermediateList[j]);
}
}
return intermediateList2;
}
console.log(intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]));
console.log(intersection([5, 10, 15, 20, 40, 32], [32, 15, 88, 1, 5, 7, 40], [1, 10, 15, 5, 20, 40, 32]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could reduce the arguments and return a single array with common values.
const intersection = (...array) => array.reduce((a, b) => a.filter(v => b.includes(v)));
console.log(intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]));
console.log(intersection([5, 10, 15, 20, 40, 32], [32, 15, 88, 1, 5, 7, 40], [1, 10, 15, 5, 20, 40, 32]));

Related

problem in comparing element of two array and if element matches then modifies another array value with some condition

I want to compare x and z and if element in x is present in z then push element of y in temp else push 0 in temp at the end length of z and temp should be equal.
below is my code ---
var x=[00,03,06,21]
var y=[79,11,18,14]
var temp=[]
var z=[00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]
for(var i=0;i<z.length;i++){
for(j=0;j<x.length;j++){
if(z[i]==x[j]){
// alert("hello")
temp.push(y[j])
}
}
if(z[i]!=x[j]){
temp.push(0)
}
}
console.log(temp)
console.log(z)
i getting the output as -
//temp (29) [79, 0, 0, 0, 11, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0]
//z (25) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
expected output --
//temp (25) [79, 0, 0, 11, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0]
//z (25) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24]
Once you found a common value, you need to continue the outer loop. If not found, push after finishing the inner loop.
BTW, do not forget to declare all variables.
var x = [0, 3, 6, 21],
y = [79, 11, 18, 14],
temp = [],
z = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24];
outer: for (let i = 0; i < z.length; i++) {
for (let j = 0; j < x.length; j++) {
if (z[i] === x[j]) {
temp.push(y[j]);
continue outer;
}
}
temp.push(0);
}
console.log(temp);
console.log(z);
A version without a label.
var x = [0, 3, 6, 21],
y = [79, 11, 18, 14],
temp = [],
z = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24];
for (let i = 0; i < z.length; i++) {
let value = 0;
for (let j = 0; j < x.length; j++) {
if (z[i] === x[j]) {
value = y[j];
break;
}
}
temp.push(value);
}
console.log(temp);
console.log(z);
Finally, a shorter approach with an object for the replacement values.
var x = [0, 3, 6, 21],
y = [79, 11, 18, 14],
z = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
values = x.reduce((r, k, i) => (r[k] = y[i], r), {}),
temp = z.map(k => values[k] || 0);
console.log(temp);
console.log(z);

Retrieve selected columns of a 2 dimensional array

I need to retrieve selected columns of a 2 dimensional array, I have a 2 dimensional array
var indexes = [2,3,5];
var data = [
["Head1","Head2","Head3","Head4","Head5", "Head6"],
[10,11,12,13,14,15,16],
[20,21,22,23,24,25,26],
[30,31,32,33,34,35,36],
];
The expected is
var result = [
[13,14,16],
[23,24,26],
[33,34,36],
]
How do I get the result array, while I must be able to dynamically change the index array of positions.
I have tried to remove the first Header
data.shift();
With right indices, you could map the values.
var indices = [2, 3, 5],
data = [["Head1", "Head2", "Head3", "Head4", "Head5", "Head6"], [10, 11, 12, 13, 14, 15, 16], [20, 21, 22, 23, 24, 25, 26], [30, 31, 32, 33, 34, 35, 36]],
result = data.slice(1).map(a => indices.map(i => a[i]));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
ES5
var indices = [2, 3, 5],
data = [["Head1", "Head2", "Head3", "Head4", "Head5", "Head6"], [10, 11, 12, 13, 14, 15, 16], [20, 21, 22, 23, 24, 25, 26], [30, 31, 32, 33, 34, 35, 36]],
result = data.slice(1).map(function (a) {
return indices.map(function (i) {
return a[i];
});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to find the Minimum number of swaps required for sorting an array of numbers in descending order in javascript

I'm trying to get my code to do this:
Original array = [1,2,3,4] swap once-> [4,2,3,1] swap again->[4,3,2,1]
Therefore result is 2
But it's not working. Here's what I have so far:
function check(arr){
var sarr = [];
var cnt = 0;
var arrL = arr.length;
// Create a second copy of the array for reference
var arrCopy = [...arr];
for(let i=0; i<arrL;i++){
var maxV = Math.max(...arr);
sarr.push(maxV);
let pos = arr.indexOf(maxV);
// Remove the found number
arr.splice(pos,1);
// Check if the index of the number in the new array is same with the copy, if not then there was a swap
let ai =arrCopy.indexOf(maxV);
let si =sarr.indexOf(maxV);
if (ai !== si && (i+1)!=arrL && pos !== 0){
cnt++;
};
}
console.log(cnt);
}
check([1, 2, 3, 4, 5, 6]);//Result should be 3
check([6,5,4,3,2,1]); //result should be 0
check([1,2,3,4]); //result should be 2
check([1,3,2,5,4,6]); //result should be 3
check([1,2,10,4,5,6,7,8,9,3,12,11]);//result should be 6
check([ 49, 37, 9, 19, 27, 3, 25, 11, 53,  42, 57, 50, 55,  56, 38, 48, 6, 33, 28, 8, 20, 31, 51, 14, 23, 4, 58, 52, 36, 22, 41, 47, 39, 2, 7, 13, 45, 1, 44, 32, 10, 15, 21, 30, 17,  60, 29, 5, 59, 12, 40, 24, 54, 46, 26, 43, 35, 34, 18, 16]);//result should be 54
Can someone please let me know what I'm doing wrong?
I would start with a copy of the array in descending order for getting the right index of the items.
For practical reasons, (or just a shorter conception of the loop with including check and decrement), I loop from the end of the array.
Then I check the value of array and reversed at the dame index and go on with the iteration.
If not the same value, the items at the wanted position i and the actual position p are swapped and the count incremented.
At the end the count is returned.
function check(array) {
var reversed = array.slice().sort((a, b) => b - a),
count = 0,
i = array.length,
p;
while (i--) {
if (array[i] === reversed[i]) continue;
p = array.indexOf(reversed[i]);
[array[i], array[p]] = [array[p], array[i]];
count++;
}
console.log(...array);
return count;
}
console.log(check([1, 2, 3, 4, 5, 6])); // 3
console.log(check([6, 5, 4, 3, 2, 1])); // 0
console.log(check([1, 2, 3, 4])); // 2
console.log(check([1, 3, 2, 5, 4, 6])); // 3
console.log(check([1, 2, 10, 4, 5, 6, 7, 8, 9, 3, 12, 11])); // 6
console.log(check([ 49, 37, 9, 19, 27, 3, 25, 11, 53,  42, 57, 50, 55,  56, 38, 48, 6, 33, 28, 8, 20, 31, 51, 14, 23, 4, 58, 52, 36, 22, 41, 47, 39, 2, 7, 13, 45, 1, 44, 32, 10, 15, 21, 30, 17,  60, 29, 5, 59, 12, 40, 24, 54, 46, 26, 43, 35, 34, 18, 16])); // 54
.as-console-wrapper { max-height: 100% !important; top: 0; }
function minimumSwaps(arr) {
var count = 0;
arr.sort((a, b) => {
if (a < b) {
count++;
}
});
return count;
}
console.log(minimumSwaps([1, 2, 3, 4, 7, 6, 5]));

Restructure one dimensional array into variable length two dimension array

I am trying to convert a one dimensional array into a two dimensional array where the length of the rows are different depending on the maximum number of columns which is supplied as an argument. I basically want to include every nth index till the end of array is reached or max number of columns are done whatever happens earlier. So for the following input:
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20]
columns = 7
I want the following output:
[1, 4, 7, 10, 13, 16, 19]
[2, 5, 8, 11, 14, 17, 20]
[3, 6, 9, 12, 15, 18]
I have tried the following code but it only works for few values:
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
function getOutput(arr, columns) {
var rows = Math.ceil(arr.length / columns);
var res = [];
for (var i = 0; i < rows; i++) {
tmp = [];
for (var j = 0, index = i; j < columns; j++) {
if (index < arr.length)
tmp.push(arr[index]);
index += rows;
}
res.push(tmp);
}
return res;
}
console.log(getOutput(array, 7))
JSFiddle available here: https://jsfiddle.net/varunsharma38/fwfz4veo/4/
I do not understand what I am missing. Although, I would not mind using some libraries, I would prefer a vanilla JS based solution.
Thanks in advance!!
Here is another solution using array#reduce.
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
columns = 7,
result = arr.reduce((r,v,i,a) => {
var index = i% (Math.ceil(a.length/columns));
r[index] = r[index] || [];
r[index].push(v);
return r;
},[]);
console.log(result);

jquery multidimensional array shuffle random

I want to minimize my code from:
myArrayA = [1, 2, 3, 4, 5];
fisherYates(myArrayA);
myArrayB = [6, 7, 8, 9, 10];
fisherYates(myArrayB);
myArrayC = [11, 12, 13, 14, 15];
fisherYates(myArrayC);
myArrayD = [16, 17, 18, 19, 20];
fisherYates(myArrayD);
myArrayE = [21, 22, 23, 24, 25];
fisherYates(myArrayE);
To:
var multArr = [[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]];
fisherYates(multArr);
The output I want is like this:
[4,2,3,5,1],[7,10,6,9,8],[11,15,12,14,13],[18,17,16,20,19],[22,21,25,23,24]
I tried this code:
http://jsfiddle.net/arrow/yFn8U/
function fisherYates(myArray) {
var i = myArray.length, j, tempi, tempj;
if (i === 0) return false;
while (--i) {
j = Math.floor(Math.random() * (i + 1));
tempi = myArray[i];
tempj = myArray[j];
myArray[i] = tempj;
myArray[j] = tempi;
}
}
var multArr = [[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]];
fisherYates(multArr);
But my code only randomizes the order of the chunks not the values in each chunk.
The output I want is like this:
[4,2,3,5,1],[7,10,6,9,8],[11,15,12,14,13],[18,17,16,20,19],[22,21,25,23,24]
I want each chunk inside the array to be in the same order but each chunk must be randomized.
Is there a way to do this with jQuery?
I also wonder how to get values from the shuffled/randomized array?
At the moment I get the values like this:
myArrayA[i]
myArrayB[i]
myArrayC[i]
myArrayD[i]
myArrayE[i]
I would guess I will get them with something like:
multArr [[0][i]];
multArr [[1][i]];
multArr [[2][i]];
multArr [[3][i]];
multArr [[4][i]];
Finally I wonder if minimizing the code will give better performance?
If you simply want to run an operation over all the elements in an array, then you should use map or forEach. I'm sure jquery provides shims for these methods in older browsers. So if we assume you're using your original fisherYates function unaltered, we might have something like this:
var multArr = [[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]];
multArr.forEach(fisherYates);
On accessing the elements, you're almost right, but you have one set too many of brackets :
multArr[1]; // == [6, 7, 8, 9, 10]
multArr[1][3]; // == 9
I wouldn't speculate about the performance, if you're really worried you should put together a jsperf test case.
All you need is jQuery's .each() method, like so:
$.each(multArr, function(i) { fisherYates(this) });
See console on this working example
Fiddle Code
function fisherYates(myArray) {
var i = myArray.length, j, tempi, tempj;
if (i === 0) return false;
while (--i) {
j = Math.floor(Math.random() * (i + 1));
tempi = myArray[i];
tempj = myArray[j];
myArray[i] = tempj;
myArray[j] = tempi;
}
}
$(function() {
$("button").on("click", function(e) {
multArr = [[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]];
$.each(multArr, function(i) { fisherYates(this) });
console.log(multArr)
})
})
Check out my code here. Basically just looped over the elements of the multidimensional array and run the fisherYates on them like so:
function fisherYates(myArray) {
for(var i = 0; i< myArray.length; i++) {
k = myArray[i].length;
while(k--){
j = Math.floor(Math.random() * (myArray.length - 1));
tempk = myArray[i][k];
tempj = myArray[i][j];
myArray[i][k] = tempj;
myArray[i][j] = tempk;
}
}
}
Now if you wanted to do this for an n-dimensional array you're going to have to do it recursively, which would be fun, but I think that is more than you were asking for. If not I can update it later.

Categories