what's up? I hope you going well.
So, my question is, I have a array with number that I have to compare with another arrays (like 1 to X), what is the best way to:
1º compare the arrays and retrieve the numbers that are equals.
2º the numbers of elements that are equal (without using .length on the array with numbers are equals).
Example:
Array 1 = [1, 3, 4, 5, 6, 7, 8, 9, 11, 13, 16]
Array 2 = [1, 2, 3, 7, 9, 12, 16, 17]
That way, the total numbers is 5
And the numbers are: [1, 3, 7, 9, 16]
My method is using forEach and compare each item and using .length on the array with the numbers that are equals, there's another way or best way to do this?
Another example using more arrays:
Arr1 = [1, 2, 3, 5, 6, 7, 8, 10, 15]
Arr2 = [
[1, 3, 5, 7, 8, 9, 10, 11, 12],
[2, 5, 6, 7, 9, 10],
[1, 3, 5, 7, 10, 11, 13, 14, 15]
]
// Output
6, [1, 3, 5, 7, 8, 10]
5, [2, 5, 6, 7, 10]
7, [1, 3, 5, 6, 7, 10, 15]
Thanks for the answer.
I like using Set for this purpose. You can create a Set from your first array and then any lookup in that Set (using Set.has) is O(1) efficiency.
const arr1 = [1, 3, 4, 5, 6, 7, 8, 9, 11, 13, 16];
const arr2 = [1, 2, 3, 7, 9, 12, 16, 17];
const arr1Items = new Set(arr1);
const matched = arr2.filter(el => arr1Items.has(el));
console.log(matched.length, matched);
Arr2 is an array, not an object, your code would change accordingly
Arr1 = [1, 2, 3, 5, 6, 7, 8, 10, 15]
Arr2 = [
[1, 3, 5, 7, 8, 9, 10, 11, 12,],
[2, 5, 6, 7, 9, 10],
[1, 3, 5, 7, 10, 11, 13, 14, 15,]
]
Given that, the solution is a oneliner:
res = Arr2.map(a=>a.filter(x=>Arr1.indexOf(x)!=-1).length)
It should be straightforward but, just in case:
The [].indexOf(el) method give you the position of the parameter in the array, if that element is not present it will return -1. Therefore, the function
x => Arr1.indexOf(x)!=-1
returns true or false if x is present or not in the Arr1 array
The [].filter(fn) method use the fn function to evaluate every array element and give as result an array with the evaluated true elements.
a.filter(x => Arr1.indexOf(x)!=-1)
Means give me all the elements of array a presents in Arr1
Now we just have to count the lenght of that array
a.filter(x => Arr1.indexOf(x)!=-1).length
and pass this count to the [].map(fn) method to have the result we need.
The function I wrote below will give the results you want, but remember the function returns an array of arrays, even if the second parameter had only one array or was an array of elements instead of array of arrays (Works for both).
Arr1 = [1, 2, 3, 5, 6, 7, 8, 10, 15]
Arr2 = [
[1, 3, 5, 7, 8, 9, 10, 11, 12],
[2, 5, 6, 7, 9, 10],
[1, 3, 5, 7, 10, 11, 13, 14, 15]
]
Arr3 = [1, 5, 6, 9, 12, 15, 17]
function check(base_array,search_values)
{
if(base_array.length===0 || search_values.length===0)
{
return [];
}
else if(Array.isArray(search_values[0]))// Check if second parameter is an array of arrays.
{
var result=[];
search_values.forEach(search=>{
var result_sub=[];
search.forEach(key=>{
if(base_array.includes(key))
{
result_sub.push(key);
}
});
result.push(result_sub);
});
return result;
}
else
{
var result=[];
search_values.forEach(key=>{
if(base_array.includes(key))
{
result.push(key);
}
});
return [result];
}
}
console.log("Array of Arrays");
console.log(check(Arr1,Arr2));
console.log("Array of Elements");
console.log(check(Arr1,Arr3));
From the returned result you can loop through the value to get the elements and the number of elements by checking length of array.
result.forEach(element=>{
console.log(result.length, result);// number of elements doesn't have to be passed
});
What the Function does is it checks if any array is empty , then returns empty array [], if the second array is an array of arrays it loops through each array and then to each element in the sub array and checks if it exists in the first array, else if the array was array of elements, then it just loops through the elements and checks if it exists in the first array. And returns the result stored
Related
Suppose I have an array of
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
And I want to split it in 3, with two arrays containing the first and last X elements of the original array, and the third array containing the remaining elements, like so:
#1 - [0, 1, 2]
#2 - [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
#3 - [13, 14, 15]
Is there a shorter/better way of doing that instead of:
const splitBy = 3;
const originalArray = Array.from(Array(16).keys());
const result = [
originalArray.slice(0, splitBy),
originalArray.slice(splitBy, -splitBy),
originalArray.slice(-splitBy),
];
console.log(result)
"better" is subjective... however, if you need this more than once, a generic function could be an option:
function multiSlice(a, ...slices) {
let res = [], i = 0
for (let s of slices) {
res.push(a.slice(i, s))
i = s
}
res.push(a.slice(i))
return res
}
// for example,
const originalArray = Array.from(Array(16).keys());
console.log(multiSlice(originalArray, 3, -3))
console.log(multiSlice(originalArray, 2, 5, 10, 12))
I want to filter a large array list into multiple arrays for every 5 items in a certain way so that [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] would be [[1, 2, [3, 4, 5]], [6, 7, [8, 9, 10]]] or [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] would be [[1, 2, [3, 4, 5]], [6, 7, [8, 9, 10]], [11, 12, [13, 14, 15]]]. (All arrays will be a multiple of 5 in my program.)
How would I do this?
Right now I'm doing this
for (var i = 1; i < (stoneTextureUnfiltered.length+1)/1.01; i++) {
stoneTexture.push([stoneTextureUnfiltered[i], stoneTextureUnfiltered[i+1], stoneTextureUnfiltered[i+2], [stoneTextureUnfiltered[i+3], stoneTextureUnfiltered[i+4], stoneTextureUnfiltered[i+5]]]);
}
but it doesn't seem to be working.
Thanks,
-Voxel
Assuming you've chunked the array already into parts of 5 with these answers and it's stored in a variable named chunks, to wrap the last 3 in each chunk you can use map:
const final = chunks.map((chunk) => [chunk[0], chunk[1], chunk.slice(2)]);
You add the first and second elements to the new list, then add the rest of the chunk as a whole.
Demo below:
// using second answer
var perChunk = 5 // items per chunk
var inputArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
var chunks = inputArray.reduce((resultArray, item, index) => {
const chunkIndex = Math.floor(index/perChunk)
if(!resultArray[chunkIndex]) {
resultArray[chunkIndex] = [] // start a new chunk
}
resultArray[chunkIndex].push(item)
return resultArray
}, [])
// answer below
const final = chunks.map((chunk) => [chunk[0], chunk[1], chunk.slice(2)]);
console.log(final);
As you can see, it works nicely!
I have an array of unsorted number and another array of sorted number, like
const unSortedArray = [54, 23, 55, 76, 9, 11];
const sortedArray= [1, 2, 3, 4, ...., 100]
How could I find out the first element appears in my sortedArray which should also be an element existed in my unSortedArray? In above example, should return 9 because 9 existed in unSortedArray as well as it positioned prior to other element in sortedArray
Note, I used 1, 2, 3, 4 in my above example, but my real world example was not number but is GUID, let's say we cannot apply sort method on unSortedArray then pick the first element.
I have thought about union both arrays, but how to union both while not break the sorting in sortedArray?
Here is some example
1) output should be 1, because even element 1, 2, 9 and 10 exists in both array, 1 has prior order than 2, 9, 10 in sortedArray
const unSortedArray = [54, 23, 55, 76, 9, 10, 2, 1];
const sortedArray= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
2) output should be 9, because even element 9 and 10 exists in both array, 9 has prior order than 10 in sortedArray
const unSortedArray = [54, 23, 55, 76, 10, 9];
const sortedArray= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
3) output should be '' because no element in unSortedArray appears in sorted Array
const unSortedArray = [54, 23, 55, 76, 11];
const sortedArray= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
A quick and dirty way to do it with a for loop:
const unSortedArray = [54, 23, 55, 76, 9, 11];
const sortedArray= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let firstVal;
for (i = 0; i < sortedArray.length; i++) {
if (unSortedArray.includes(sortedArray[i])) {
firstVal = sortedArray[i];
break;
}
}
console.log(firstVal);
You can create a Set from the unSortedArray and use set.has() in your predicate for sortedArray.find():
const unSortedArray = [54, 23, 55, 76, 9, 11];
const sortedArray= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const setHasValue = set => value => set.has(value);
const firstElement = sortedArray.find(setHasValue(new Set(unSortedArray)));
console.log(firstElement);
It would be a good idea to construct a look up table for unsorted array items. Such as
{ 54: true
, 23: true
, 55: true
.
.
11: true
}
This would be an O(k) task where k is the number of elements of the unsorted array. Then find the first item in the sorted array that returns true. This should be an O(n) task where n is the number of elements of the sorted array. Yielding a linear time solution.
This should do it.
function getFirst(usa,sa){
var h = usa.reduce((r,n) => (r[n] = true, r), {});
return sa.find(n => h[n]);
}
var r = getFirst([54,23,55,76,9,11], Array.from({length:100}, (_,i) => i+1));
console.log(r);
When there are two arrays arr1, arr2 and assigning one array to another making one array null doesn't affect other? Any Specific reason??Array assignment in JavaScript. consider the below example..
var arr1 = [1,2,3,4,5,6,7,8,9,0];
var arr2 = arr1;
arr1[2]=10;
console.log(arr1);//[1, 2, 10, 4, 5, 6, 7, 8, 9, 0]
console.log(arr2);//[1, 2, 10, 4, 5, 6, 7, 8, 9, 0]
arr1 = [];
console.log(arr1);//[]
console.log(arr2);//[1, 2, 10, 4, 5, 6, 7, 8, 9, 0]
I have an array, which contains duplicate values. How can I push duplicates in to another array?
let arr1 = [1, 5, 3, 6, 9, 5, 1, 4, 2, 7, 9], and duplicates array should be dupArr = [1, 5, 9]
You could filter the array by storing the previous checked values in a Set, which is here a closure.
var array = [1, 5, 3, 6, 9, 5, 1, 4, 2, 7, 9],
duplicates = array.filter((s => v => s.has(v) || !s.add(v))(new Set));
console.log(duplicates);