Find count of matched elements in two arrays? - javascript

So I want to create a function in js which takes two arrays and compare them and give a score depending on how many spots in the two arrays match. Is it right or it's bd written. I am new on coding.
Another problem I have is when I try to execute it on chrome's console. It says that compare is not defined
let score = 0;
function compare(arr1, arr2) {
for (let i = 0; i < arr2.length; i++) {
for (let j = 0; j < arr1.length; j++) {
if(arr1[j] === arr2[i]){
score++;
}
}
}

You can use .reduce() to find count of matched elements:
let arr1 = [1, 2, 3, 4, 5],
arr2 = [3, 4, 5, 6, 7],
compare = (a1, a2) => arr1.reduce((a, c) => a + arr2.includes(c), 0);
console.log(compare(arr1, arr2));
Alternatively, you can use .filter() to find array of matched elements and use its length to determine the count.
let arr1 = [1, 2, 3, 4, 5],
arr2 = [3, 4, 5, 6, 7],
compare = (a1, a2) => arr1.filter(v => arr2.includes(v)).length;
console.log(compare(arr1, arr2));
Docs:
Array.prototype.reduce()
Array.prototype.includes()
Array.prototype.filter()
Arrow Functions

This should work for you:
Updated the code as required by you :
let arr1 = [1, 2, 3, 4];
let arr2 = [3,2,3,4,5];
function compare(arr1,arr2){
let count=0;
const max=arr1.length>arr2.length ? arr2.length : arr1.length;
for(var i=0;i<max;i++){
if(arr1[i]==arr2[i]){
count++;
}
}
return count;
}
console.log(compare(arr1,arr2));

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

javascript: return every possible pairs in array

the title explains it all
somehow I'd like to use the method "Combination" that math has,
this is the Wikipedia page to be clear: https://en.wikipedia.org/wiki/Combination
I have already found the solution with two loops, I want to do it in one loop
example:
const arr = [1, 2, 3, 4]
function getPairs(arr) {
/*
desired return:
[
[1, 2], [1, 3], [1, 4],
[2, 3], [2, 4],
[3, 4]
]
*/
}
You can use Array.flatMap() to iterate the array, and Array.map() to iterate all items after the current (by slicing from index + 1), and return the pair.
const getPairs = arr => arr.flatMap((a, i) => arr.slice(i + 1).map(b => [a, b]))
const arr = [1, 2, 3, 4]
const result = getPairs(arr)
console.log(result)
You can use simple for-loops.
function getPairs(arr = []) {
if (!arr.length) return []
const pairs = []
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
pairs.push([arr[i], arr[j]])
}
}
return pairs
}
console.log(getPairs([1, 2, 3, 4]))
For a simple combination algorithm, you need to loop twice through the array.
Looking for the math expression, we see that we need to get all elements from the array (let's call this element i) and match all subsequent elements from i with it (let's call those j)
Following it, what we have is something like:
let array = [1, 2, 3, 4];
let results = [];
// Loop through the items on your array (get `i`)
for (let i = 0; i < array.length - 1; i++) {
// Loop after the current 1st loop item (get `j`) and push them to a new array
for (let j = i + 1; j < array.length; j++) {
results.push([array[i], array[j]]);
}
}
console.log(results);
Using slice and map
const arr = [1, 2, 3, 4]
console.log(arr.slice(0, -1).map((x, i) => arr.slice(i+1).map(y => [x, y])))

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

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

Move every other value from array into a new array

I have two one-dimensional arrays, a and b. a has values and b is empty. The length of a is an even number. I'd like to remove every other value from a and move them to b, in the same order as they were placed in a.
var a = [1, 2, 3, 4, 5, 6], b = [];
becomes
var a = [1, 3, 5], b = [2, 4, 6];
I figured that filter would do the trick but I'm not that happy with the performance of it since the average length of a is 300-400.
b = a.filter((i, idx) => {
return idx % 2 == 0;
});
a = a.filter((i, idx) => {
return idx % 2 == 1;
});
I've also been looking at lodash to see if that library had anything that might help me and the only function that's near what I'm looking for is _.chunk(array, \[size=1\]).
I appreciate any and all help to help me figure out a better, faster way to do this.
Since you mentioned lodash you could do this with _.partition:
let a = [1, 2, 3, 4, 5, 6];
let b = [];
let i = -1;
[a, b] = _.partition(a, (item) => i++ % 2);
console.log(a);
console.log(b);
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
Partition's predicate is the identity function, which doesn't include the index of the item, so this comes with a compromise of an external index i.
Of course, you could always wrap this functionality into it's own function:
const splitEvenOdd = (array, i = -1) => _.partition(array, (item) => i++ % 2);
let a = [1, 2, 3, 4, 5, 6];
let b = [];
[a, b] = splitEvenOdd(a);
console.log(a);
console.log(b);
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
Vanilla JS ES5, simple and clean.
var a = [1, 2, 3, 4, 5, 6], b = [];
for(var i = a.length-1; i >= 0; i--) {
if(i % 2 === 1) {
b.unshift(a.splice(i, 1)[0])
}
}
Basically, it is iterating through a backwards, and if the condition is true splicing the item und adding it as first item of b.
To loop through the source once, the values can be added to a specific array depending on the index. For example:
const source = [1, 2, 3, 4, 5, 6];
let arrs = [[],[]];
for(let i = 0; i< source.length; i++)
arrs[i%2].push(source[i]);
let [a,b] = arrs;
console.log(a);
console.log(b);
Alternatively, if it's important to alter the original arrays, a can be filled in a direct iteration, since the index being processed is always ahead of the one being filled:
let a = [1, 2, 3, 4, 5, 6], b= [];
for(let i = 0; i< a.length; i++)
(i % 2 ? b : a)[Math.floor(i/2)] = a[i];
a.splice(a.length/2);
console.log(a);
console.log(b);
The best performance you can get for this is 0(n) or linear time since you have to iterate through the entire array. What may help is reducing the number of loops
var a=[];
var b=[];
function splitArray(arr)
{
for (var i=0;i<arr.length;++i)
{
if (arr[i]%2 == 0)
b.push(arr[i]);
else
a.push(arr[i]);
}
}
What this does is reduces the number of times you have to iterate through the original array from 2 to 1

Categories