Im stuck on a piece of javascript for the last 4 hours!
The question is how do I count similarities between 2 arrays like so:
arrayA = [a,b,c,d,e,f,g];
arrayB = [c,d,e];
The answer shoud be three. The only piece of code I have at the moment produces a infinite loop :(
Pleas help
One way would be to filter arrayA by checking each to see if it's in arrayB, then getting the length of the new array:
arrayA.filter(function(el) {
return arrayB.indexOf(el) >= 0;
}).length;
This uses:
Array#indexOf
Array#filter
Array#length
NB that the first two are not available in old browsers, so need to be shimmed using the code in the links given.
here you go (cross browser solution):
[note that .filter() method wont work in IE8 and other old browsers, so i suggest the following approach]
1) define the function:
function count_similarities(arrayA, arrayB) {
var matches = 0;
for (i=0;i<arrayA.length;i++) {
if (arrayB.indexOf(arrayA[i]) != -1)
matches++;
}
return matches;
}
2) call it:
var similarities = count_similarities(arrayA, arrayB);
alert(similarities + ' matches found');
if you don't bother about old browsers support, i'd highly suggest lonesomeday's answer.
hope that helps.
You should take each element of one array and check if it is present in the other using arrayA.indexOf(arrayB[i])
If it doesnt return -1 then increment a count variable.
At the end count is your answer.
You can go with $.inArray() function to do this
http://api.jquery.com/jQuery.inArray/
$(function () {
arrayA = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
arrayB = ['c', 'd', 'e'];
var matchCount = 0;
$.each(arrayB, function (index, value) {
if ($.inArray(value, arrayA) != -1)
matchCount++;
});
alert("Matched elements : " + matchCount);
});
Related
I have an array var plans=[a, b, c, d ]; with prices based monthly any yearly.
Consider- a and b are monthly and c and d are yearly.
So, I want to split the array based on the monthly and yearly values and store the values in to separate arrays
var monthly_plans=[]; and var yearly_plans=[]
So, how do I do this?
I have used the js split() function before but on a very basic level.
You can use the slice(start, end) function on arrays, e.g.
monthly_plans = plans.slice(0,2);
yearly_plans = plans.slice(2,4);
More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
split() is a method of the String object, not of the Array object.
From what I understand from your question, you need the Array.prototype.slice() method instead:
The slice() method returns a shallow copy of a portion of an array
into a new array object.
Syntax
arr.slice([begin[, end]])
In conclusion, you may want to do something like this:
var monthly_plans = plans.slice(0, 2);
var yearly_plans = plans.slice(2);
And the ES5 approach:
var plans=[a, b, c, d];
var monthly_plans = plans.filter( plan => plan==='monthly condition' );
var yearly_plans = plans.filter( plan => plan==='yearly condition' );
I think it will be a better avenue to use a for.
Example:
for (var i=0;i<plans.length;i++)
{
if(plans[i] == 'monthly condition')
{
monthly_plans.push(plans[i]);
}
else
{
yearly_plans.push(plans[i]);
}
}
Based on your post, the solution will not involve split(). If you know in advance which plan designations are monthly and which are yearly:
var plans = ['a', 'b', 'c', 'd', 'm', 'y', ....... 'n'],
count = plans.length, i = 0;
var monthly_designations = ['a', 'b', 'm'],
yearly_designations = ['c', 'd', 'y'];
for(; i < count; i++) {
if (monthly_designations.indexOf(plans[i]) !== -1) {
monthly_plans.push(plans[i]);
} else {
if (yearly_designations.indexOf(plans[i]) !== -1) {
yearly_plans.push(plans[i]);
}
}
}
Then just check the plans array against the known designations to filter the contents into the correct sub-arrays monthly_plans and yearly_plans.
I am trying to use this code in Javascript to verify prime numbers using an array to store them:
var nprimi = [2];
function verifica(x)
{
var i;
var x;
var k;
//for (k in nprimi)
for (k=0;k<nprimi.length;k++)
{
if (nprimi[k]==x)
return true;
else if (x%nprimi[k]==0)
return false;
}
for (i=k+1;i<x;i++)
{
if (x%i==0)
return false;
}
nprimi.push(x);
return true;
}
My problem is:
If I use
for (k=0;k<nprimi.length;k++)
for loop is running correctly, but using
for (k in nprimi)
doesn't work.
It seems that after each nprimi.push(x) the number of elements in objetc nprimi is always zero.
Maybe it is a very stupid error, but I am not able to find it!
Thank you very much for helping!
Ciao Giancarlo,
the short answer is: in JavaScript you do not use for..in to loop through arrays.
You use for..in to loop through objects.
A really good explanation is to be found here.
Edit:
Another thing. In your code, in the function verifica, you have an x parameter and an x local variable, you should really remove the var x declaration.
function verifica(x)
{
var i;
var x; // <-- this shouldn't be here.
It's not working because that's not what for-in is for. for-in loops through the names of enumerable object properties, not array indexes. Those names are strings, not numbers. So following your loop, k+1 will be a concatenation operation, not an addition operation. That is, if k is "2", then k+1 will be "21".
Don't use for-in to loop through arrays unless you know what you're doing and use safeguards. More about looping arrays in this answer.
In for loop after the loop the value of k will be incremented (k++). But in the case of for-in it will not happen. So in that case you have to do it manually. I have updated the function:
function verifica(x)
{
var i;
var x;
var k;
for (k in nprimi)
//for (k=0;k<nprimi.length;k++)
{
if (nprimi[k]==x)
return true;
else if (x%nprimi[k]==0)
return false;
}
k++; //This is the line making difference in for-in loop
for (i=k+1;i<x;i++) {
if (x%i==0)
return false;
}
nprimi.push(x);
return true;
}
for in iterates over the indexes of the array
var myArray = ['a', 'b', 'c'];
for (k in myArray) {
console.log(k + ' -> ' + myArray[k]);
}
outputs:
0 -> 'a'
1 -> 'b'
2 -> 'c'
As you can see, the k variable does not contain the 'a', 'b', 'c'
Thought I would share this in case people needed it as I couldn't find something similar.
I am wondering if it is possible to remove an item from an array even if duplicates of that item exist.
Lets look at some code:
var myArray = ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'd', 'd', 'e'],
itemToRemove = 'a',
itemToAdd = 'f';
For the example above, I want to remove itemToRemove from the array, BUT, I do not want to remove all of them, just 1. I then want to add itemToAdd.
To give a little context, I am build a category/personality based quiz, each answer to a question has a category. I want to store all chosen categories in an array, then display a result dependent on which category is most common at the end of the quiz.
Where the question comes in is the User can go back and change their choice if they want, so if they do change their mind, I need to remove the previous category and add the new one.
So this answer to this is actually very simple.
var index = myArray.indexOf(itemToRemove);
if(index != -1) {
array.splice(index, 1);
}
As the indexOf function only finds the first index and only finds 1 index this can be used to remove just 1 of the array items.
We also need to be careful with indexOf as it is not supported with IE8, as always IE8 is a pain in the ass.
So the following code can make indexOf work for you, it must be run before you use the function.
if (!Array.prototype.indexOf)
{
Array.prototype.indexOf = function(elt /*, from*/)
{
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++)
{
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
Sourced from here:
Why doesn't indexOf work on an array IE8?
If anyone has any ideas of a better way to do this they would be much appreciated.
I use lodash to insert an item into an array if it's not there, and remove it if it exists, kind of "toggling".
My code looks like this:
var items = ['a', 'b', 'c'];
var itemToToggle = 'a';
if (_.includes(items, itemToToggle)) {
_.pull(items, itemToToggle)
}
else {
items.push(itemToToggle)
}
Which seems not perfect enough.
Can I simplify it to, ideally, have something like _.toggle(items, itemToToggle)?
Another way to do it would be to use lodash's xor
var items = ['a', 'b', 'c'];
var itemToToggle = 'a';
new_array = _.xor(items, [itemToToggle])
return new_array // ['b', 'c']
Which will add the item if it does not exist, and remove if it does.
It does this by comparing the two arrays (items and [itemToToggle]) and returning a new array that is a merge of the two arrays, minus duplicates.
Your code seems fine to me. The only thing, I can think of is using the length to see if an item was removed, and if not, add it:
function toggleValueInArr(arr, value) {
var originalLength = arr.length; // cache the original length
_.pull(arr, value).length === originalLength && arr.push(value); // check if the length is the same as the original - ie no item was not removed. If so, push it.
return arr;
}
I have:
var array = new Array();
array.push("A");
array.push("B");
array.push("C");
I want to be able to do something like:
array.remove("B");
but there is no remove function. How do I accomplish this?
I'm actually updating this thread with a more recent 1-line solution:
let arr = ['A', 'B', 'C'];
arr = arr.filter(e => e !== 'B'); // will return ['A', 'C']
The idea is basically to filter the array by selecting all elements different to the element you want to remove.
Note: will remove all occurrences.
EDIT:
If you want to remove only the first occurence:
t = ['A', 'B', 'C', 'B'];
t.splice(t.indexOf('B'), 1); // will return ['B'] and t is now equal to ['A', 'C', 'B']
Loop through the list in reverse order, and use the .splice method.
var array = ['A', 'B', 'C']; // Test
var search_term = 'B';
for (var i=array.length-1; i>=0; i--) {
if (array[i] === search_term) {
array.splice(i, 1);
// break; //<-- Uncomment if only the first term has to be removed
}
}
The reverse order is important when all occurrences of the search term has to be removed. Otherwise, the counter will increase, and you will skip elements.
When only the first occurrence has to be removed, the following will also work:
var index = array.indexOf(search_term); // <-- Not supported in <IE9
if (index !== -1) {
array.splice(index, 1);
}
List of One Liners
Let's solve this problem for this array:
var array = ['A', 'B', 'C'];
1. Remove only the first:
Use If you are sure that the item exist
array.splice(array.indexOf('B'), 1);
2. Remove only the last:
Use If you are sure that the item exist
array.splice(array.lastIndexOf('B'), 1);
3. Remove all occurrences:
array = array.filter(v => v !== 'B');
DEMO
You need to find the location of what you're looking for with .indexOf() then remove it with .splice()
function remove(arr, what) {
var found = arr.indexOf(what);
while (found !== -1) {
arr.splice(found, 1);
found = arr.indexOf(what);
}
}
var array = new Array();
array.push("A");
array.push("B");
array.push("C");
remove(array, 'B');
alert(array);
This will take care of all occurrences.
Simply
array.splice(array.indexOf(item), 1);
Simple solution (ES6)
If you don't have duplicate element
Array.prototype.remove = function(elem) {
var indexElement = this.findIndex(el => el === elem);
if (indexElement != -1)
this.splice(indexElement, 1);
return this;
};
Online demo (fiddle)
const changedArray = array.filter( function(value) {
return value !== 'B'
});
or you can use :
const changedArray = array.filter( (value) => value === 'B');
The changedArray will contain the without value 'B'
In case of wanting to remove array of strings from array of strings:
const names = ['1','2','3','4']
const excludeNames = ['2','3']
const filteredNames = names.filter((name) => !excludeNames.includes(name));
// ['1','4']
You have to write you own remove. You can loop over the array, grab the index of the item you want to remove, and use splice to remove it.
Alternatively, you can create a new array, loop over the current array, and if the current object doesn't match what you want to remove, put it in a new array.
use:
array.splice(2, 1);
This removes one item from the array, starting at index 2 (3rd item)
use array.splice
/*array.splice(index , howMany[, element1[, ...[, elementN]]])
array.splice(index) // SpiderMonkey/Firefox extension*/
array.splice(1,1)
Source:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
This only valid on str list, look up this
myStrList.filter(item=> !["deletedValue","deletedValue2"].includes(item))
Here is the simplest answer.
First find index using indexofand then
if index exist use splice
const array = ['apple', 'banana', 'orange', 'pear'];
const index = array.indexOf('orange'); // Find the index of the element to remove
if (index !== -1) { // Make sure the element exists in the array
array.splice(index, 1); // Remove the element at the found index
}
console.log(array); // ["apple", "banana", "pear"]