I am trying to be able to make a list of all instances of a Constructor, so I can check if all of these fit criteria in an IF statement
For Example:
function People() {
People.allInstances = [];
People.allInstances.push(this);
}
var Carry = new People();
var Gary = new People();
var Parry = new People();
console.log(People.allInstances);
However, I seem to lose all data except for the last instance I created. How can I make that list/array, and then use that array to test if any of them has a certain property?
The constructor runs every time an instance is constructed with it, but you only want to create an empty array once:
function People() {
People.allInstances.push(this);
}
People.allInstances = [];
I want to add items to an array skipping the duplicates. However for some reason only one item is being added and the second item is not being added. Here is my code.
var add = ['email1#gmail.com', 'email2#gmail.com', 'email1#gmail.com'];
var main_messages = []
var from
function findMessages(messageList) {
return messageList = from;
}
add.map(function(map){
from = map
if(main_messages.find(findMessages) === undefined){
main_messages.push(map)
}
});
console.log(main_messages)
So the expected output should be
['email1#gmail.com', 'email2#gmail.com']
But the output I'm getting in this code is only
['email1#gmail.com']
What am I doing wrong and how can I fix this problem?
Looks like you're missing a = in your return statement of findMessages, so you're basically setting from to messageList instead of comparing. Here's the fixed code
var add = ['email1#gmail.com', 'email2#gmail.com', 'email1#gmail.com'];
var main_messages = []
var from
function findMessages(messageList) {
return messageList === from;
}
add.map(function(map){
from = map
if(main_messages.find(findMessages) === undefined){
main_messages.push(map)
}
});
console.log(main_messages)
Consider using the JavaScript 1.6 / ECMAScript 5 native filter method of an Array in the following way:
var add = ['email1#gmail.com', 'email2#gmail.com', 'email1#gmail.com'];
var main_messages = add.filter(function(v, i, a) {return a.indexOf(v) === i;});
Another solution that should offer better performance O(x) would be to use array.reduce:
main_messages = Object.keys(add.reduce(function (p,c) {return (p[c] = true,p);},{}));
Both solutions will result in messages containing:
["email1#gmail.com", "email2#gmail.com"]
In case you need support for Browsers that don't have this implemented, as always there is a pollyfill offered by Mozilla (see bottom of page)
i think your error in below code
function findMessages(messageList) {
return messageList = from;
}
here i think you return to its parent so it is showing one vale.
for this you need to store messageList = from in a var, then return that variable.
var x = messageList;
return x;
You could implement a uniq function. Which is a specialised form of filter.
var add = ['email1#gmail.com', 'email2#gmail.com', 'email1#gmail.com'];
var main_messages = uniq(add);
function uniq(arr) {
var result = [];
for (var i = 0; i < arr.length; i++) {
if (result.indexOf(arr[i]) === -1) {
result.push(arr[i]);
}
}
return result;
}
console.log(main_messages)
On the other hand, map will always return an array of the same size, unless of course you muck about with assignments, etc.
map passes each element of an array to a callback function you use to modify the individual element without touching the actual array.
Think of it as 1 in 1 out, and so on, but you get the chance to change what is in the array, not how many things are in there. The idea is that there that the array resulting from map has the same length of the input array, but different content.
Methods that can result in an array of different size are filter and reduce for instance.
So being super-terse you could also do this:
var add = ['email1#gmail.com', 'email2#gmail.com', 'email1#gmail.com'];
var main_messages = add.filter( (el, idx, input) => input.indexOf(el) === idx );
console.log(main_messages)
You can use indexOf function in order to check the duplicate. You can try below way to add items to your array without duplicates.
var add = ['email1#gmail.com', 'email2#gmail.com', 'email1#gmail.com'];
var main_messages = []
add.map(function(map){
if(main_messages.indexOf(map) == -1){
main_messages.push(map)
}
});
console.log(main_messages);
Here is an easy answer: https://stackoverflow.com/a/18328062/5228251
Why do it the hard way, it can be done more easily using javascript filter function which is specifically for this kind of operations:
var add = ['email1#gmail.com', 'email2#gmail.com', 'email1#gmail.com'];
var main_messages = []
main_messages = add.filter( function( item, index, inputArray ) {
return inputArray.indexOf(item) == index;
});
------------------------
Output: ['email1#gmail.com', 'email2#gmail.com']
Depending on your needs, using a Set instead of an array may be what you are looking for:
The Set object lets you store unique values of any type, whether
primitive values or object references.
var add = ['email1#gmail.com', 'email1#gmail.com', 'email2#gmail.com', 'email1#gmail.com'];
// Init from an iterable.
var main_messages = new Set(add);
// Add a new email (not previously in the set).
main_messages.add('email3#gmail.com');
// Try to add an existing email, does nothing.
main_messages.add('email1#gmail.com');
console.log('main_messages:')
main_messages.forEach(msg => console.log('-', msg));
Of course, this option is only viable if you keep the data stored in the Set. It would be quite inefficient to convert it into an array after each insertion.
Set is an ES2015 feature. You may want to check the compatibility table and consider using a polyfill if needed.
In jQuery and node.js environments, suppose you have the following:
var object = new Soda().drink("Coke").drink("Pepsi").drink("7Up");
Now let's say I have a list of N drinks and I don't want to hard code this programatically:
var object = new Soda().drink("D1").drink("D2").drink("Dn")...
What is the programatic approach to this problem if I need this to run sequentially and I can't use:
var object = new Soda();
for (var in j){
object.drink(i);
}
The line new Soda().drink("Coke").drink("Pepsi").drink("7Up") implies that .drink() returns a value that by itself is a valid object to call .drink() again with (either the original object, or some other object that encapsulates the modified state).
If that is the case, you could:
var currentDrinkable = object;
for(var drink in drinks) {
currentDrinkable = currentDrinkable.drink(drink)
}
I have an svg map with several points where I want to store the initial position of each point in an array. And each point has it's own ID, like point_1, point_2 etc.
I have attached a click handler to each of these and run a function when they are clicked.
So what I want to do in this function is to check if the array already contains the information of the clicked element. If it doesn't, I want to create it.
This is what I want to do, in pseudo code
var arrPoints = [];
zoomToPoint('point_1');
function zoomToPoint(data_id) {
// Does array already contain the data?
if (!arrPoints.data_id) {
// Add data to the array
arrPoints.data_id.clientX = somevalue;
arrPoints.data_id.clientY = somevalue;
}
}
This would basically create an array that looks like this:
arrPoints.point_1[]
arrPoints.point_2[]
Where I can access the data in each .point_1 and .point_2.
But I can't create an array based on a variable, like this:
arrPoints.data_id = [];
Because I end up with data_id as the actual name, not the variable that data_id actually is. So how is this usually accomplished? How can I identify each point to the actual array?
Sorry for my lack of basics
Just use an object:
var arrPoints = {};
zoomToPoint('point_1');
function zoomToPoint(data_id) {
// Does array already contain the data?
if (!arrPoints[data_id]) { // square brackets to use `data_id` as index
// Add data to the array
arrPoints[data_id] = {};
arrPoints[data_id].clientX = somevalue;
arrPoints[data_id].clientY = somevalue;
}
}
I want to return the var "source" value for all the element, now when I put the "source" out of each function, it become undefined.I want to return the whole source array. How to do that? any help would be truly appreciated -
function _getSource(){
var product = fpd.getProduct(true);
$(product[0].elements).each(function(i, elem) {
var source = elem.parameters['source'];
})
return source;
alert (source);
}
Assuming that you're actually after an array containing the source property of each element:
function _getSource(){
var product = fpd.getProduct(true);
return $(product[0].elements).map(function(i, elem) {
return elem.parameters['source'];
}).get(); // .get() turns jQuery collection into an array
}
.map is a very good replacement for a .each / push combo. It comes from functional languages where the "map" function just takes an array, transmutes each elements, and returns a new array of those transmuted results.
The final .get is not strictly necessary if you don't mind getting an array-like result back rather than a proper array.
When you write var source you are declaring a new variable scoped to the function of the each callback. Declare it outside and get rid of the var so you are just assigning instead of redeclaring, and you probably also want to build up an array and not just assign. Something like this:
function _getSource(){
var product = fpd.getProduct(true);
var sources = [];
$(product[0].elements).each(function() {
sources.push(elem.parameters['source']);
})
return sources;
}
source is only defined inside the each function because you var'd it there.
Try this instead:
function _getSource() {
return $(fpd.getProduct(true)[0].elements).map(function() {return this.parameters['source'];});
}