How to get list of child nodes? - javascript

Below, I have attached an image with some console output. What I would like to do is, grab all the numbered nodes (so, 0 and 1, but there could be more or less), and put them into an array (like [0, 1]).
Is this possible?

Use .toArray().
var listOfNodes = $list.toArray();
EDIT: As was pointed out by SterlingArcher, there's a better option in ES6 in the form of Array.from.
var listOfNodes = Array.from($list);

You can use a simple for-loop
To go through these arrays just don't use forEach, with that you will go through every property but you want the numbers only
Jquery uses a combination of arrays and associative array (objects in Javascript)
So it has auto incremented keys and words as keys

Related

How to synchronise for loop iteration one after another

I have a dropdown of country on a webpage. I need to validate the country names in drop down is sorted using Protractor-Cucumber.
I located all options in dropdown using element.all() and used a forEach loop on array. For each iteration, it extract the text and add to another array. Since extracting text takes some time, my resultant array does not have texts in same order as it appears in drop down.
element.all(by.css('ul.sbsb_b')).then(function(allOptions){
allOptions.forEach(function(optn){
optn.getText().then(function(text){
result.push(text);
})
})
});
If my dropdown contains options as A,B,C,D then resultant array should give me in same order. Above logic works fine for less number of options. I want forEach to do iteration one by one instead of all at once because of asynchronous nature.
The method I would attempt for this issue would be to convert your ElementArrayFinder into an array of strings directly using .getText(). I would imagine this would preserve the order but cannot say for sure.
element.all(by.css('ul.sbsb_b')).getText().then(function(allOptions){
console.log(typeof allOptions)
console.log(Array.isArray(allOptions))
}
To preform your validation there are two approaches you could take which do not require any particular order of the state names array you are extracting.
You could sort the array and then expect them both to be equal.
element.all(by.css('ul.sbsb_b')).getText().then(function(allOptions){
expect(allOptions.sort()).toEqual(expectedStates);
}
Or you could validate that the array you have created is the same length as your expected array of states and then verify that every expected state appears at least once in the created array
element.all(by.css('ul.sbsb_b')).getText().then(function(allOptions){
expect(allOptions.length).toBe(expectedStates.length);
for(let i = 0; i < expectedStates.length; count++){
expect(allOptions).toContain(expectedStates[i]);
}
}

format json data in javascript like a pivot table

I have the the following data being returned by my api.
[{"category":"Amazon","month":"Feb","total":9.75},
{"category":"Amazon","month":"Mar","total":169.44},
{"category":"Amazon","month":"Apr","total":10.69},
{"category":"Amazon","month":"May","total":867.0600000000001},
{"category":"Amazon","month":"Jun","total":394.43999999999994},
{"category":"Amazon","month":"Jul","total":787.2400000000001},
{"category":"Amazon","month":"Aug","total":1112.4400000000003},
{"category":"Amazon","month":"Sep","total":232.86999999999998},
{"category":"Amazon","month":"Oct","total":222.26999999999998},
{"category":"Amazon","month":"Nov","total":306.09999999999997},
{"category":"Amazon","month":"Dec","total":1096.2599999999998}]
I want to format it so that the months are all grouped under each category like this:
[{"category":"Amazon","month":{"Jan":9.75,"Feb":9.75,"Mar":9.75,"Apr":9.75,etc...}]
How can I do this with javascript?
What I'm ultimately trying to do is to display some pivoted data in a table. I'm not sure what the best design is to accomplish this.
Right now, I'm just setting up a table dynamically and adding in the data corresponding to each row. Are there better design patterns for doing this?
You can reduce the array of objects to an object using the categories as keys, and adding the months, and then map it back to an array again
var arr = [{"category":"Amazon","month":"Feb","total":9.75},
{"category":"Amazon","month":"Mar","total":169.44},
{"category":"Amazon","month":"Apr","total":10.69},
{"category":"Amazon","month":"May","total":867.0600000000001},
{"category":"Amazon","month":"Jun","total":394.43999999999994},
{"category":"Amazon","month":"Jul","total":787.2400000000001},
{"category":"Amazon","month":"Aug","total":1112.4400000000003},
{"category":"Amazon","month":"Sep","total":232.86999999999998},
{"category":"Amazon","month":"Oct","total":222.26999999999998},
{"category":"Amazon","month":"Nov","total":306.09999999999997},
{"category":"Amazon","month":"Dec","total":1096.2599999999998}];
var o = arr.reduce( (a,b) => {
a[b.category] = a[b.category] || [];
a[b.category].push({[b.month]:b.total});
return a;
}, {});
var a = Object.keys(o).map(function(k) {
return {category : k, month : Object.assign.apply({},o[k])};
});
console.log(a);
I would take the following approach:
Write down on a piece of paper how to solve the problem (the "algorithm").
Flesh out this algorithm with more details. Sometimes this is called "pseudo-code".
Convert the pseudo-code into JavaScript.
For instance, your algorithm might look like this:
Create a new thing to hold the results.
Loop through the elements in the input.
For each element in the input, update the results thing.
Return the result.
Sometimes it helps to read out the algorithm aloud to yourself. Or animate the algorithm on a blackboard. Or talk through the algorithm with someone nearby.
The pseudo-code might be:
Create a new array containing a new object to hold the results, with a category property set to "Amazon", and a months property set to an empty object.
Loop through the elements in the input array.
For each element, add a new property to the months property of the results object, whose key is the value of the month property from the element, and whose value is the value of the total property from the element.
Return the result.
If you have specific questions about any of those steps, you can research it further, or ask, such as:
How do I create a new array, with an object inside?
How do I loop through the elements of an array?
How do I retrieve a property from an object?
How do I add a new key/value pair to an object?
How do I return the result?
If you are unfamiliar with any of the terms used above--such as array, object, property, key, value, or element--research them and make sure you know what they mean. Knowing and using correct terminology is the first step to successful programming!
When converting your algorithm into JS, write it step by step, and test it at each phase. For instance, start with a version which doesn't loop over the input at all, and make sure it produces a correct output of [{category: "Amazon", month: {}}]. Walk though your code in the debugger at this and each following step--if you don't know how to use the debugger, learning that should be your first priority! If you want to check a little bit of syntax, to make sure it does what you think, just try it out by typing it into the console. If you don't know what the console is, learning that should be another top priority.
All the above assumes that you've got a single Amazon category. If you are going to have multiple categories, and want multiple objects (one for each) in your output array, then start over from the top and write the algorithm and pseudo-code which can handle that.

How can I work with the Name of an Array?

Situation: I have an array called "array1" with some strings in it.
For example, when I type array1.length , then the program gives me the amount of strings in the array back. What do I have to do to get "6" back (The amount of letters in the array name "array1")
maybe you could youst wrap the arrays with numbers in one array and the other ones in another array and just use the wrapper array you need.
without seeing your code this is the best solution i can give you

How do I create a multi-dimensional array in Javascript like shown in this picture?

There are fixed three columns in it. The rows are added dynamically and may go up-to few thousands also.
I should also be able to iterate through the array and filter Id & Values based on level.
Is this possible ? How?
Arrays of Arrays are easy.
[[1, 234,'Apple'],[2,23,'Sunday'], ....]
To add something to the array, push use push. To iterate forEach. filter is not yet in the JS standard, but here is a polyfill: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
I suggest for your problem to look at not building an Array of Arrays, but model each row as a JS object:
{level: 1, id: 234, value: 'Apple'}
that way you can write more semantic code like
myObjectList.filter(function(obj){ return obj.level > 1 })
rather than using array indexes everywhere.
In general if you ant get an idea what you can do with JS built-ins like Array, check the JS reference at the Mozilla Developer Network. Its pretty good and has lots of examples for each Array function like forEach or find, or filter.

High performance JS map for int-string pairs

I need a high performance map in Javascript (hashmap or whatever) that maps int(s) to string(s). The map would be used to build some sections of the webpage after dom is ready. I know simple javascript object also works like a map but I need to work with best performance.
I would like to initialize the map with all data pairs just at once by appending a string to the webpage while generating the response page from server.
Any ways how to improve performance of javascript map for int- string pairs or are there any implementations for the same ?
--
Using jQuery 1.7
Ok, I'll post it here since it's more of an answer:
Use an array. Taken into account that any implementation will have to use js primitives and objects, you'll be hard pressed to find something more performant than that.
Arrays in most (all?) implementations of javascript can be sparse. So array.length will return the index of last element + 1, but in sparse case the array will not have all elements allocated and will use object property semantics to access it's elements (meaning, it's effectively a hashtable with ints as keys).
It basically gives you the behavior you're looking for.
In case of negative ints, use a second array.
In relation to a single statement initialization: you can't do it in general, since it bases itself on implicitly knowing the item index.
What you can do is to append something along the lines:
var arr = [];
arr[int1] = val1;
arr[int2] = val2;
arr[int3] = val3;
arr[int4] = val4;
...
arr[intn] = valn;
I mean you have to list (Number, String) pairs somehow anyway.
Please check out this jperf test case, and draw your conclusion.
Objects are also sparse. Arrays are simply specialized objects that account for their own length among other things.
I think you should use the following
var l_map = {};
to add an element use
l_map[<your integer>] = <your string>
and to retrieve is
var l_value = l_map[<your integer>];
This is one way to solve your problem.
The second way is quite simple just use an array (or list) because it stores the values based on position as follows:
var l_array = [];
to add element at the last use : l_array.push(<your string>);
to add element at a specified position : l_array.splice(<position>,0,<your string>);
and to retrieve use : l_array[<posit>];

Categories