Count occurrences between two arrays in javascript - javascript

So, lets say I have these two arrays:
const arr1 = ["apple", "orange", "banana", "mango", "cherry"]
const arr2 = ["apple", "mango"]
How to get the number of occurrences in arr1 from arr2. All the strings in both arrays will be unique and there won't be duplicates. Obviously, the result in this concrete case is 2.
What I have tried:
const arr1 = ["apple", "orange", "banana", "mango", "cherry"]
const arr2 = ["apple", "mango"]
let count = 0
arr2.forEach(i =>
arr1.includes(i) ? count++ : count );
console.log(count);
The problem is I have to use this in few cases and the count variable is always changing, depending on what you click and you cannot rely on its value.
Thank you in advance!

Check if this is what you are looking for:
const arr1 = ["apple", "orange", "banana", "mango", "cherry"];
const arr2 = ["apple", "mango"];
// count items
const count = arr1.filter(i => arr2.includes(i)).length;
console.log(count) // displays 2

Related

Why is splice working with for loop, but not with map in javascript?

For a 2D array:
var fruits = [["Banana", "Orange", "Apple", "Pear"],
["Banana", "Orange", "Apple", "Pear"],
["Banana", "Orange", "Apple", "Pear"],
["Banana", "Orange", "Apple", "Pear"]];
why the difference between map and for loop?
var newArrayMap = fruits.map(f => f.splice(1,2));
console.log(newArray);
[["Orange", "Apple"], ["Orange", "Apple"], ["Orange", "Apple"], ["Orange", "Apple"]]
for (var i = fruits.length - 1; i >= 0; i--){
fruits[i].splice(1,2);
}
console.log(fruits);
[["Banana", "Pear"], ["Banana", "Pear"], ["Banana", "Pear"], ["Banana", "Pear"]]
Array#splice returns the deleted parts of the array.
In the first loop with map, you take the returned value of splice.
In the second loop with for, you never use the returned value of splice. splice mutates the array and because of that, you get an array without unwanted parts.

Decrement the value of a variable at every function call

I am creating a slot machine program using JavaScript, and want to decrement the value of coins at every function call. For example, coins = 20. It should decrement after every time the casino() function is called. Basically the function can be called as many times until coins = 0.
Is this a situation where the application of let vs var comes into play?
Here is a snippet of my code:
let reel1 = ["cherry", "lemon", "apple", "lemon", "banana", "banana", "lemon", "lemon"]
let reel2 = ["lemon", "apple", "lemon", "lemon", "cherry", "apple", "banana", "lemon"]
let reel3 = ["lemon", "apple", "lemon", "apple", "cherry", "lemon", "banana", "lemon"]
let slotReel = []
let coins = 20
function casino(r1, r2, r3) {
coins = coins - 1
let random1 = reel1[Math.floor(Math.random() * reel1.length)]
let random2 = reel2[Math.floor(Math.random() * reel3.length)]
let random3 = reel3[Math.floor(Math.random() * reel3.length)]
slotReel.push(random1, random2, random3)
//.....some logic
}
casino(reel1, reel2, reel3);
console.log("Coins after running the function:", coins);
You need create a loop to call the function until the coins are gone.
let reel1 = ["cherry", "lemon", "apple", "lemon", "banana", "banana", "lemon", "lemon"]
let reel2 = ["lemon", "apple", "lemon", "lemon", "cherry", "apple", "banana", "lemon"]
let reel3 = ["lemon", "apple", "lemon", "apple", "cherry", "lemon", "banana", "lemon"]
let slotReel = []
let coins = 20;
function casino(r1, r2, r3) {
let random1 = reel1[Math.floor(Math.random() * reel1.length)]
let random2 = reel2[Math.floor(Math.random() * reel3.length)]
let random3 = reel3[Math.floor(Math.random() * reel3.length)]
slotReel.push(random1, random2, random3)
//.....some logic
}
while( coins > 0 ) {
casino();
coins--;
}

Match Arrays Value To Return All Matched Occurrences

I'm in need of little help with records matching in two arrays with different length.
Requirements:
Find same values between two arrays
Return only that matched
Push matched value back to the array where the values were found.
Example:
var findFrom = ["Apple", "Mango", "Orange", "Mango", "Mango", "Apple"];
var findTheseValues = ["Apple", "Mango"];
Returned Array = ["Apple", "Apple("Matched")", "Orange", "Mango", "Mango("Matched")", "Mango", "Mango(Matched)", "Apple("Matched")"];
**// Push matched values next to the value that was matched in the FindFrom Array**
I tried:
var findFrom = ["Apple", "Mango", "Orange", "Banana", "Orange", "Orange","Orange"];
​
var findTheseValues = ["Orange", "Banana"];
​
for(let i = 0; i < findFrom.length; i++){
​
if (findFrom[i] === findTheseValues[i] // toString() if required){
console.log(findFrom[i]);
}
}
If I just replace the 'i' in the if condition for find These Values with 0, it returns the matched values but I don't want it to match just one value - it should loop over both arrays.
Tried Find from ES 6 but it just returns one value that matched.
I'm happy to explain more if required & I appreciate the help! :)
You can use .map() and .includes() methods:
let findFrom = ["Apple", "Mango", "Orange", "Mango", "Mango", "Apple"],
findTheseValues = ["Apple", "Mango"];
let result = findFrom.map(s => s + (findTheseValues.includes(s) ? ` (${s})` : ''));
console.log(result);
Docs:
Array.prototype.map()
Array.prototype.includes()
This solution works for me:
var findFrom = ["Apple", "Mango", "Orange", "Mango", "Mango", "Apple"];
var findTheseValues = ["Apple", "Mango"];
var solution = [];
for(let i = 0; i < findFrom.length; i++){
solution.push(findFrom[i]);
if (findTheseValues.indexOf(findFrom[i]) !== -1) {
solution.push(findFrom[i] + ' (Matched)');
}
}
console.log(solution)
This loops through the array, tries to find the element at the index in "findthesevalues"- then pushes the "matched" string to the new array if we find a match
You can use Arrays map method which return a new set of array with matched text appended.
var returnedArray = findFrom.map((ele)=> {
if(findTheseValues.indexOf(ele)!==-1){
return [ele, ele+"(matcheed)"] // return a pair with appended matched
}else{
return ele;
}
}).join().split(',') // to flatten array.
Here's a decent solution that uses native Array methods instead of for-loops, which is always a better idea, imho.
Also, this will also allow you to look for the same value more than once, e.g. include a value more than once in your search.
let findFrom = ["Apple", "Mango", "Orange", "Mango", "Mango", "Apple"];
// try either of the following
let findTheseValues = ["Apple", "Mango"];
//let findTheseValues = ["Apple", "Mango", "Mango"];
let results = [];
findFrom.forEach((i) => {
const match = findTheseValues.filter((a) => i === a);
const result = match.length > 0 ? match.concat(i) : i;
results.push(i);
if (match.length > 0) {
match.forEach(m => results.push(m));
};
});
console.log(results);
I would do something like this
var findFrom = ["Apple", "Mango", "Orange", "Mango", "Mango", "Apple"];
var findTheseValues = ["Apple", "Mango"];
var matches = findFrom.map((e, i)=>{
return r = findTheseValues.includes(e) ? e + '(matched)' : e;
});
console.log(matches);
I am writing this answer because all other solutions proposed are based on linear searching over findTheseValues array, whereas the total computational complexity can be definitely reduced using a different data structure: I am talking about Sets or Maps. They are probably implemented using a hash table and as ECMAScript Standard says:
must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection.
So, my solution is almost equal to the others, except for data structure used.
let findTheseValuesSet = new Set(findTheseValues);
let newArray = [];
findFrom.forEach(elem => {
newArray.push(elem);
if (findTheseValuesSet.has(elem))
newArray.push(elem + '(Matched)');
});

array.push adding key named push

What am I missing here? Shouldn't this just push 'hi' into the [4] instead of naming it with a key named 'push'?
<script>
Array = ["Banana", "Orange", "Apple", "Mango"];
Array.push = ('hi');
console.log(Array);
</script>
You should do like this -
var sampleArr = ["Banana", "Orange", "Apple", "Mango"];
sampleArr.push('hi');
console.log(sampleArr );
The correct way would be :
var arr = ["Banana", "Orange", "Apple", "Mango"];
arr.push('hi');
console.log(arr);
Your syntax is incorrect.
var array = ["Banana", "Orange", "Apple", "Mango"];
array.push("hi");
http://www.w3schools.com/jsref/jsref_push.asp

Javascript Remove specific only needed n-th elements of array

For example i have an array
var fruits = ["Banana", "Orange", "Apple", "Mango", "App", "Man"];
The code
fruits.splice(2, 2);
Return me output
Banana,Orange,App,Man
But how to return only 1,3,4 elements from array without looping?
So i will get
Orange,Mango,App
I imaging must be something like that
fruits.splice( fruits.indexOf(Orange,Mango,App), 1 );
You can use filter to filter out certain items:
fruits = fruits.filter(function (e, i) {
return i === 1 || i === 3 || i === 4;
});
Or if you want to keep certain items based on their identity (which seems to be what you're trying to do at the end of your question):
fruits = fruits.filter(function (e) {
return e === "Orange" || e === "Mango" || e === "App";
});
The same as JLRishe's answer but with the addition that you can pass in a list of those elements that you want to keep:
var fruits = ["Banana", "Orange", "Apple", "Mango", "App", "Man"];
var list = 'Orange, Mango, App';
alert(strip(fruits, list)); // ["Orange", "Mango", "App"]
function strip(arr, list) {
list = list.split(', ');
return arr.filter(function (el) {
return list.indexOf(el) > -1;
});
}
You may combine slice and splice methods:
var fruits = ["Banana", "Orange", "Apple", "Mango", "App", "Man"];
fruits.splice(2,1);
var x = fruits.slice(1,4);
x;
Explanation:
splice deletes 1 element starting at index 2 ( ie. "Apple" ).
slice extracts 3 elements starting at index 1 ( ie. "Orange", "Apple", "Mango", "App"; remember that at this time, the array no longer contains "Apple").
Variation (non-destructive):
var fruits = ["Banana", "Orange", "Apple", "Mango", "App", "Man"];
var x = fruits.slice(1,2).concat(fruits.slice(3,5));
x;

Categories

Resources