JavaScript - Merge two arrays with different sizes - javascript

I have two arrays:
var array1= [1,3,5,7,9,11]
var array2= [undefined,4,6]
I need to merge one element of the array1, then one element of the array2, etc. This is my code:
function mergeArrays(array1, array2){
var array3 = [];
maxlength = Math.max(array1.length, array2.length);
for(i=0;i<maxlength;i++){
array3.push(array1[i]);
array3.push(array2[i]);
}
return console.log(array3);
}
The output now is:
array3 = [1,undefined,3,4,6,7,undefined,9,undefined,11,undefined]
I need the output to be:
array3 = [1,undefined,3,4,6,7,8,11]
I mean, I can't use ( != undefined), because if I have an undefined in the middle of the array it has to be there.

You are not placing a check for the length of shorter array.
Your function is fetching a value which is higher than the length of the array, hence, extra undefined. This should do the job
var array1 = [1, 3, 5, 7, 9, 11];
var array2 = [undefined, 4, 6];
function mergeArrays(array1, array2) {
var array3 = [];
maxlength = Math.max(array1.length, array2.length);
for (i = 0; i < maxlength; i++) {
if (i < array1.length) array3.push(array1[i]);
if (i < array2.length) array3.push(array2[i]);
}
return console.log(array3);
}
mergeArrays(array1, array2);

You can grab the max length of the two arrays and loop until you hit that value. While looping, check if the length has been exceeded and push onto the result.
const allEqual = (...args) =>
((head, ...tail) => tail.every(curr => curr === head))
(args.map(v => JSON.stringify(v)));
const test = ({ actual, expected }) => {
console.log(JSON.stringify(actual));
console.log(allEqual(actual, expected));
};
const interlaceArrays = (...arrays) => {
const result = [];
const maxLen = Math.max(...arrays.map(({ length }) => length));
for (let i = 0; i < maxLen; i++) {
arrays.forEach(arr => {
if (i < arr.length) result.push(arr[i]);
})
}
return result;
};
const
odd = [1, 3, 5, 7, 9, 11],
even = [undefined, 4, 6],
other = ['a', 'b'];
test({
actual: interlaceArrays(odd, even),
expected: [1, undefined, 3, 4, 5, 6, 7, 9, 11]
});
test({
actual: interlaceArrays(odd, even, other),
expected: [1, undefined, 'a', 3, 4, 'b', 5, 6, 7, 9, 11]
});
.as-console-wrapper { top: 0; max-height: 100% !important; }

Related

how to concat two arrays into one and remove all similar values?

I have a problem needing two arrays containing some similar values and different values. I need to concat the arrays into a new array and remove the similar values only showing the individual values. something like arr1 = [1, 44, 2, 3, 5], arr2 = [33, 1, 2, 3, 4, 5], arr3 = [], return arr3 [44, 33, 4]. I have tried a few different ways with no success, one using a nested for loop and the other using .filter(). Any thoughts on how I can solve this? Here is my code:
const arrayDiffs = (arr1, arr2) => {
let arr3 = [];
for (let i = 0; i < arr1.length; i++) {
if (arr3.indexOf(arr1[i]) === -1) {
arr3.push(arr1[1]);
}
for (let n = 0; n < arr2.length; n++) {
if (arr3.indexOf(arr2[n]) === -1) {
arr3.push(arr2[n]);
}
}
return arr3;
};
}
console.log(arrayDiffs([1, 44, 2, 3, 5], [33, 1, 2, 3, 4, 5]));
I have also tried this way:
let arr3 = [];
const arrayDiffs = (arr1, arr2) => {
arr3 = arr1.concat(arr2);
arr3 = arr3.filter(function(item, index) {
if(arr3.indexOf(item) == index){
return true;
}
return false;
});
}
console.log(arrayDiffs([1, 44, 2, 3, 5], [33, 1, 2, 3, 4, 5]));
const myFunc = (a,b) => {
const a_but_not_b = a.filter(x=>!b.includes(x));
const b_but_not_a = b.filter(x=>!a.includes(x));
return [...a_but_not_b,...b_but_not_a];
}
console.log(myFunc([1,2,3],[2,3,4]));
But, let me explain more:
Use filter and includes to get difference.
Last I concat the arrays using spread operator [...a,...b].
Using your first method only we can achieve this. You have to do the following modifications.
for (let i = 0; i < arr1.length; i++) {
if (arr2.indexOf(arr1[i]) === -1) { // first compare the value with arr2 and arr1 and push the non-available values into arr3
arr3.push(arr1[i]);
}
}
for (let n = 0; n < arr2.length; n++) {
if (arr1.indexOf(arr2[n]) === -1) { //compare the value with arr1 and arr2 and push the non-available values into arr3
arr3.push(arr2[n]);
}
}
const arrayDiffs = (arr1, arr2) => {
let arr3 = [];
for (let i = 0; i < arr1.length; i++) {
if (arr2.indexOf(arr1[i]) === -1) {
arr3.push(arr1[i]);
}
}
for (let n = 0; n < arr2.length; n++) {
if (arr1.indexOf(arr2[n]) === -1) {
arr3.push(arr2[n]);
}
}
return arr3;
}
console.log(arrayDiffs([1, 44, 2, 3, 5], [33, 1, 2, 3, 4, 5]));
Have you tried sets in javassript. I think they are used for storing only unique elements.this will bring down you complexity to O(N), where N is total number of elements in arrays. Example :
const letters = new Set()
[...arr1,...arr2].filter(e=>!(arr1.includes(e)&&arr2.includes(e)))
var arr1 = [1, 44, 2, 3, 5],
arr2 = [33, 1, 2, 3, 4, 5],
arr3 = [...arr1,...arr2]
.filter(e=>!(arr1.includes(e)&&arr2.includes(e)));
console.log(arr3);

array rotation results my array with empty value why is that

i am writing a simple program of array rotation.
when i console log element array , it includes empty along with other values.. why is that and whats the fix?
how can i remove empty ?
let arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let num = prompt("Enter Rotation Value : ");
const rotateFunc = (arr, d) => {
// debugger;
let result = [];
let temp = [];
let element = [];
for (let i = 0; i < arr.length; i++) {
if (i < d) {
temp[i] = +arr[i];
} else {
element[i] = +arr[i];
}
}
console.log(temp);
console.log(element);
result = element.concat(temp);
console.log(result);
};
rotateFunc(arr1, num);
results:
temp array console log result: (3) [1, 2, 3]
element array console log result: (9) [empty × 3, 4, 5, 6, 7, 8, 9]
and final result console log : (12) [empty × 3, 4, 5, 6, 7, 8, 9, 1, 2, 3]
When you assign to an element in the middle of an array, without assigning to the indexes before it, those earlier indexes still exist, they're marked "empty". Since you don't start assigning to element[i] until i is at least d, all the previous elements are empty.
Rather than assigning to specific indexes, use push() to append to the arrays starting from the beginning. Then you won't have gaps in the array.
let arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let num = prompt("Enter Rotation Value : ");
const rotateFunc = (arr, d) => {
// debugger;
let result = [];
let temp = [];
let element = [];
for (let i = 0; i < arr.length; i++) {
if (i < d) {
temp.push(arr[i]);
} else {
element.push(arr[i]);
}
}
console.log(temp);
console.log(element);
result = element.concat(temp);
console.log(result);
};
rotateFunc(arr1, num);
You also need to update your final array and remove the first d elements. You can use splice() to achieve it. It modifies the array in place
let arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let num = prompt("Enter Rotation Value : ");
const rotateFunc = (arr, d) => {
// debugger;
let result = [];
let temp = [];
let element = [];
for (let i = 0; i < arr.length; i++) {
if (i < d) {
temp[i] = +arr[i];
} else {
element[i] = +arr[i];
}
}
element.splice(0,d);
console.log(temp);
console.log(element);
result = element.concat(temp);
console.log(result);
document.write(result);
};
rotateFunc(arr1, num);

Remove only first duplicate value and all other matching values after comparing two arrays

I have two array , I am trying to remove all matching value from 1st array which are in 2nd.
But if value is duplicate it should only remove 1st duplicate value.
For example - my two arrays are
arr1=[1,1,2,3,4,4]
arr2=[1,3,4]
it should give result as = [1,2,4]
or if my arrays are
arr1=[1,1,1,2,3,4,4,4]
arr2=[1,3,4]
it should give result as = [1,1,2,4,4]
I tried different approach using filter and includes but nothing works.
Below code removes all matching values but I want to remove all matching and only first duplicate value if it matches.
arr1 =
arr1.filter(f => !arr2.includes(f));
this.arr2.forEach(x=>{
if (this.arr1.indexOf(x)>=0)
this.arr1.splice(index,1)
})
or
this.arr1=this.arr1.filter((x,index)=>this.arr2.indexOf(x)<0 ||
this.arr1.indexOf(x)!=index )
In order to remove only the first occurrence, you can use indexOf instead. So, the solution would be:
let arr1 = [1, 1, 2, 3, 4, 4];
let arr2 = [1, 3, 4];
for (let i = 0; i < arr2.length; i++) {
if (arr1.includes(arr2[i])) {
let matchedItemIndex = arr1.indexOf(arr2[i]);
arr1[matchedItemIndex] = null;
}
}
arr1 = arr1.filter((x) => x != null);
console.log(arr1); // Expected Result: [1, 2, 4]
There are lots of ways to do this. Most of the above answers are right. But I would suggest using sets
let arr1 = [1, 1, 2, 3, 4, 4];
let arr2 = [1, 3, 4];
let result = [];
for(let i = 0; i < arr1.length; i++) {
let index = arr2.indexOf(arr1[i]);
if(index > -1) {
arr2.splice(index, 1);
} else {
result.push(arr1[i]);
}
}
console.log(result); /// [1, 2, 4]
Use Set and reduce
const process = (arr1, arr2) => {
const set2 = new Set(arr2);
return arr1.reduce((acc, curr) => {
set2.has(curr) ? set2.delete(curr) : acc.push(curr);
return acc;
}, []);
};
let arr1 = [1, 1, 2, 3, 4, 4];
let arr2 = [1, 3, 4];
console.log(process(arr1, arr2));
arr1=[1,1,1,2,3,4,4,4]
arr2=[1,3,4]
console.log(process(arr1, arr2));

JS Arrays — Reorganize 1D Array into 2D Array of N Groups Placing Values Sequentially

I've tried a few approaches to this but I can't seem to come up with a viable solution...
In short, I want to create a function to transform a 1D array of any length into a new 2D array of a specific length. Each value from the 1D array should be sequentially placed into each child-array up to the specified length, then start back at the first child-array.
Input / Desired Output Below:
function groupArray(arr, numberOfGroups) {
...
};
// Input Data
const items = [1, 2, 3, 4, 5, 6, 7];
const size = 3;
console.log(groupArray(items, size));
// Expected Output
// [[1, 4, 7], [2, 5], [3, 6]]
You could take the reminder operator % with index and wanted size of the array for getting the right target array.
const
groupArray = (array, size) => array.reduce((result, value, index) => {
const target = index % size;
if (!result[target]) result[target] = [];
result[target].push(value);
return result;
}, []);
console.log(groupArray([1, 2, 3, 4, 5, 6, 7], 3));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using nested for
function groupArray(arr, numberOfGroups) {
var result = []
for (var i = 0; i < numberOfGroups; i++) {
var subarr = []
for (var j = i; j < arr.length; j += numberOfGroups) {
subarr.push(arr[j])
}
result.push(subarr)
}
return result
};
// Input Data
const items = [1, 2, 3, 4, 5, 6, 7];
const size = 3;
console.log(groupArray(items, size));
Also something like this would do it,
you'd not need to mutate any input
const chunkify = (step, list) => list.reduce(
([chunk, rest], item, i) => {
const pick = i % step === 0;
return [
chunk.concat(pick ? item : []),
rest.concat(pick ? [] : item),
];
},
[[], []],
);
const group = (step, list, result = []) => {
if (!list.length) { return result; }
const [chunk, rest] = chunkify(step, list);
return group(step - 1, rest, [...result, chunk]);
};
const data = [1, 2, 3, 4, 5, 6, 7];
const step = 3;
console.log(
group(step, data),
);
Have method next, each call will return next index and when limit reaches numberOfGroups reset the index 0. (in this case, it will be like 0, 1, 2, 0, 1, 2....)
With this method, can easily push to corresponding output sub array.
const groupArray = (arr, numberOfGroups) => {
const output = Array.from({ length: numberOfGroups }, () => []);
const next = index => index % numberOfGroups;
arr.forEach((num, i) => output[next(i)].push(num));
return output;
};
// Input Data
const items = [1, 2, 3, 4, 5, 6, 7];
const size = 3;
console.log(groupArray(items, size));

Find Matches in Array

I have array1 = [4, 5, 6, 7, 4, 5]; and array2 = [4, 5].
And I want to match array2 in array1 and to output the number of times it matched.
var array1 = [4, 5, 6, 7, 4, 5];
var array2 = [4, 5];
function match(a1, a2) {
//matches 4,5 twice bc it is in array1
}
match(array1, array2) //output: 2;
You have to use a nested loop and compare each index of both arrays with each other.
var count = 0;
for (var i = 0; i < a1.length; i++)
{
for (var j = 0; j < a2.length; j++)
{
if (a1[i]==a2[j])
{
count +=1;
}
}
}
The best way to solve your problem is by intersection.
The solution for your problem: https://stackoverflow.com/a/1885660/4120554
What you're asking for is called an intersection. If you're only interested in the number of matches, this function should do the trick:
var array1 = [4, 5, 6, 7, 4, 5];
var array2 = [4, 5];
function intersectCount(arr1, arr2) {
var c = 0;
for(const item of arr2) {
if (arr1.indexOf(item) != -1) c++;
}
return c;
}
intersectCount(array1, array2); // result: 2
You can use below code for your question;
var array1 = [4, 5, 6, 7, 4, 5];
var array2 = [4, 5];
function match(a1, a2) {
var result = [];
for(const item of a2) {
if (a1.indexOf(item) > -1 ) {
result.push (item);
}
}
return result.length;
}
If you want to compare each index:
var match = (arr1,arr2)=>arr1.filter((el,i)=>el === arr2[i]).length;
If you want to count all elements that exist in both arrays, may unify one through a set:
function match(arr1,arr2){
var set = new Set( arr2 );
return arr1.filter( el => set.has(el) ).length;
}

Categories