Note: I just want to to understand what is $.map doing in following code..
I am working on openstack horizon,In one of the javascript file they are using $.map function Please seehorizon.d3linechar.js
My question is how $.map is works, what is $ before map. $.map is associated with javascript or jquery..
$.map(self.series, function(serie) {
serie.color = last_point_color = self.color(serie.name);
$.map(serie.data, function(statistic) {
// need to parse each date
statistic.x = d3.time.format.utc('%Y-%m-%dT%H:%M:%S').parse(statistic.x);
statistic.x = statistic.x.getTime() / 1000;
last_point = statistic;
last_point.color = serie.color;
});
});
Please read the jQuery documentation. Their are many many examples. Our folk is realy trying to help you. But what is the lack of your understanding in the $.map() function?
$ is only the namespace and makes at least the map function work. So forget about it.
map( input, outputFunction ) is iterating through the input which has to be an real array. The outputFunction, usually a self executing function, is able to manipulate the content of each element of the inputed array.
In your example:
$.map(self.series, function(serie) {
self.series is the input and each element of that array will be called as serie in the anonymous or rather self executed function.
serie.color = last_point_color = self.color(serie.name);
Change some color stuff...
$.map(serie.data, function(statistic) {
Next call of the mapping function.
// need to parse each date
statistic.x = d3.time.format.utc('%Y-%m-%dT%H:%M:%S').parse(statistic.x);
Parsing the date to a specific format like discribed in the comment.
statistic.x = statistic.x.getTime() / 1000;
Take the x value parse to a time or maybe to seconds and divide through 1000.
last_point = statistic;
Save element of serie.data to a temporar variable.
last_point.color = serie.color;
Save the color of the of the serie to the element of that serie.
});
});
All in all...
... $.map() iterates through self.series, then iterates through its children and then it looks like it changes the color of every single element to the color of that series.
$ is an alias for the jQuery object.
As for map(), it is an api function in jQuery used to convert the items in an array.
If you look at the source for map, the basic algorithm is to iterate over the passed in elems and obtain a converted value using the callback
function (elems, callback) {
var value, i = 0,
length = elems.length,
ret = [];
for (; i < length; i++) {
//alternatively, for objects, for (i in elems) {
value = callback(elems[i], i);
if (value != null) {
ret.push(value);
}
}
// Flatten any nested arrays
return concat.apply([], ret);
}
Related
I am working on a plugin with quite a few options and as a consequence I am trying to keep track of a set of elements and put them in a variable. The variable cannot be empty (but that is of no concern here). Let's say there are only two options, then the variable will hold one or two elements as a jQuery object, i.e. $("#el1, #el2"). I tried the following, but the result of adding is still $([]).
var track = $([]);
someFunc() {
if (option1) track.add("#el1");
if (option2) track.add("#el2");
}
// result is `$([])`
Note that I don't want an array back, but a jQuery selector as I posted in the example above.
You could first sort out which elements/selectors you need.
And then use these to init the track variable with an jQuery object passing in all the relevant selectors.
var track = someFunc();
// you would have to check the length of `track` first as it may be only an empty array (length == 0) and no real jQuery object
if (track.length) {
//...
}
// returns a jQuery object with all the matched elements
// or an empty array if there is no relevant selector
function someFunc() {
// place to store the selectors
var selectors = [];
// store the relevant selectors in <selectors>
if (option1) selectors.push("#el1");
if (option2) selectors.push("#el2");
// if there is at least one selector in <selectors>
if (selectors.length > 0) {
// create a jQuery object of them and return it
return $(selectors.join())
} else {
// otherwise we return an empty array
// this allows us to use .length in both cases
return [];
}
// or always return a jQuery object
// return $(selectors.join());
}
Use a array join on coma:
var elements = [];
elements.push('#one');
console.log(elements.join(','));
$(elements.join(','));
https://jsfiddle.net/8xx8x1xe/
I would like to have the same functionality as sort (eg passing a comparative function), without sorting the array, but rather call for each object a function that takes as an argument the order of that particular element.
You could then use it this way:
var users=[
{name:"Stephen",age:12},
{name:"Mike",age:17},
{name:"Jeffrey",age:32},
{name:"Anna",age:15}
]
var result=users.getOrder(
function(userA,userB)
{return userA.age-userB.age>0;},
function(user,order)
{user.num=order;});
/* result=[
{name:"Stephen",age:12,num:4},
{name:"Mike",age:17,num:2},
{name:"Jeffrey",age:32,num:1},
{name:"Anna",age:15,num:3}
]*/
I would be happy if they was a way to write this using the usual Array functions or if I will have to write the loops and sort algorithm on my own. Is there a way?
One solution is for example:
You can clone the original array and sort that using standard sort. Then you can loop through the cloned and see what the index of sorted is where their name or age matches.
for(var j =0; j<b.length;j++){
for(var k=0;k<a.length;k++){
if(b[j].name === a[k].name){
b[j].num = k;
}
}
}
See fiddle with bubblesort:
http://jsfiddle.net/GeJ6v/
Here is my solution that is O(n * sqrt(n)):
Array.prototype.getOrder=function(compareFunction,indexFunction,setFunction) {
var index={};
this.forEach(function(user) {
index[indexFunction(user)]=user;
});
newUsers= this.slice().sort(compareFunction);
newUsers.forEach(function(user,num) {
setFunction(index[indexFunction(user)],num);
});
return this;
}
http://jsfiddle.net/gFLys/
i am trying for the first time to implement OOP in javascript and i got stuck on a recursive function when i try to send an array of objects to this function. So, i have the "Pitic" class (pitic means midget in romanian) with some propreties:
function Pitic(piticID) {
this.id = piticID;
this.inaltime = null;
this.greutate = null;
this.genereazaGreutate();
this.genereazaInaltime();
}
I'm now generating some midgets and storing them in the public piticiCollection Array variable. The "genereazaGreutate" and "genereazaInaltime" are function to generate random values for the inaltime and greutate values.
var pitic = new Pitic(idPitic);
piticiCollection.push(pitic);
The problem appears when i try to send the array of midgets to a function because all i get is only the first item of the array.
So, before i call the function, i have piticiCollection array with 4 objects:
midgets are safe and sound http://img443.imageshack.us/img443/484/yr4f.png
And as soon as i call the function with the piticiCollection as a parameter i loose 3 midgets! :(
most of the midgets are gone http://img201.imageshack.us/img201/5808/7od5.png
p.s. please excuse me for my bad english..
[EDIT]
Here is a fiddle of my full code: http://jsfiddle.net/WT7Ud/ I call the function on line 56 and as soon as the debugger hits line 60 i loose array items.
I have solved my problem by creating a copy of the array before using it in the function. Strange :(
function determinaPerechi(somePitici) {
var piticDeComparat, colectieDePiticiCopy;
colectieDePiticiCopy = somePitici;
for (var i = 1; i < colectieDePiticiCopy.length; i++) {
var piticDeComparat2 = null;
piticDeComparat = colectieDePiticiCopy[0];
piticDeComparat2 = colectieDePiticiCopy[i];
if (piticDeComparat.inaltime < piticDeComparat2.inaltime) {
//Perechea poate fi prietena
}
}
//colectieDePiticiCopy.splice(0, 1);
if (colectieDePiticiCopy.length == 0) {
//alert("finish");
return;
}
determinaPerechi(colectieDePiticiCopy);
//test(ttt);
}
Your determinaPerechiPosibile is modifying the original array on this line:
colectieDePitici.splice(1, colectieDePitici.length);
In particular, it is removing all but the first element. You probably should be using slice to non-destructively extract the part of the array you want to recurse on.
As Ted Hopp mentioned, the problem appears to be the line
colectieDePitici.splice(1, colectieDePitici.length);
in combination with this line:
determinaPerechiPosibile(colectieDePiticiCopy);
If those two lines are commented out, the array maintains its original length.
I have a JSON response like this:
var errorLog = "[[\"comp\",\"Please add company name!\"],
[\"zip\",\"Please add zip code!\"],
...
Which I'm deserializing like this:
var log = jQuery.parseJSON(errorLog);
Now I can access elements like this:
log[1][1] > "Please add company name"
Question:
If I have the first value comp, is there a way to directly get the 2nd value by doing:
log[comp][1]
without looping through the whole array.
Thanks for help!
No. Unless the 'value' of the first array (maybe I should say, the first dimension, or the first row), is also it's key. That is, unless it is something like this:
log = {
'comp': 'Please add a company name'
.
.
.
}
Now, log['comp'] or log.comp is legal.
There are two was to do this, but neither avoids a loop. The first is to loop through the array each time you access the items:
var val = '';
for (var i = 0; i < errorLog.length; i++) {
if (errorLog[i][0] === "comp") {
val = errorLog[i][1];
break;
}
}
The other would be to work your array into an object and access it with object notation.
var errors = {};
for (var i = 0; i < errorLog.length; i++) {
errors[errorLog[i][0]] = errorLog[i][1];
}
You could then access the relevant value with errors.comp.
If you're only looking once, the first option is probably better. If you may look more than once, it's probably best to use the second system since (a) you only need to do the loop once, which is more efficient, (b) you don't repeat yourself with the looping code, (c) it's immediately obvious what you're trying to do.
No matter what you are going to loop through the array somehow even it is obscured for you a bit by tools like jQuery.
You could create an object from the array as has been suggested like this:
var objLookup = function(arr, search) {
var o = {}, i, l, first, second;
for (i=0, l=arr.length; i<l; i++) {
first = arr[i][0]; // These variables are for convenience and readability.
second = arr[i][1]; // The function could be rewritten without them.
o[first] = second;
}
return o[search];
}
But the faster solution would be to just loop through the array and return the value as soon as it is found:
var indexLookup = function(arr, search){
var index = -1, i, l;
for (i = 0, l = arr.length; i<l; i++) {
if (arr[i][0] === search) return arr[i][1];
}
return undefined;
}
You could then just use these functions like this in your code so that you don't have to have the looping in the middle of all your code:
var log = [
["comp","Please add company name!"],
["zip","Please add zip code!"]
];
objLookup(log, "zip"); // Please add zip code!
indexLookup(log, "comp"); // Please add company name!
Here is a jsfiddle that shows these in use.
Have you looked at jQuery's grep or inArray method?
See this discussion
Are there any jquery features to query multi-dimensional arrays in a similar fashion to the DOM?
Say I have an array in JS: var fruits = [apple,orange,banana]
I want to store the index of each fruit in variables such that at any point in time, if I add more stuff to the array, I will still know that the index of apple is X. So in this case, 0 is apple, but if I add something to the beginning of that away, the index of apple changes.
The more verbose way I can think of is to loop through the array
for (var i=0;i<fruits.length;i++) {
switch(fruits[i]) {
case:"apple"
var indexApple = i;
break;
//etc
}
}
Another way I can think of is use the value of the arrays as the variable name.
for (var i=0;i<fruits.length;i++) {
//psedo code
var 'index' + fruits[i] = i;
}
So in the end I'd have var indexApple = 0, indexOrange = 1, etc. THe key to the second method is to be able to create a dynamic variable by concatenating the string 'index' and the value of the array to create that variable. Not sure how to do that.
Note: Ideally I want the variables that store the index to be dynamically generated. Such that I only I can modify/add to the fruits array, and a new variable will be generated to store the index.
it seems like ensuring your the value of the index is legitimate will be difficult. i would include jquery and use the inArray method which returns the index of the item in the array.
function showIndexes() {
var appleIndex = $.inArray(fruits, "Apple"); //returns 0
var guavaIndex = $.inArray(fruits, "Guava"); //returns -1
fruits.unshift("Guava");
appleIndex = $.inArray(fruits, "Apple"); //returns 1
guavaIndex = $.inArray(fruits, "Guava"); //returns 0
}
The simplest solution is simply to build an Object which gives you nearly O(1) lookup time, and will scale with your array:
function LinkFruits(fruits) {
FruitLookup = {}
fruits.forEach((fruit,ind) => FruitLookup[fruit] = ind)
}
Now you can simply "lookup" your index from the FruitLookup table when needed like:
console.log("The index of apple is",FruitLookup.apple,"and for orange is",FruitLookup.orange)
Now if you modify your array you simply need to run LinkFruits(fruits).
Technical Note: If you want to fully automate this process you can look into Array.observe() which is now deprecated. Or overload the push and pop methods of this array to trigger the update before falling back to the default prototype methods.