I try to merge two node list in one but when I concat in one array, there is two time the same node. Concat do not search if nodes to insert already exist in array...
var firstNodelist = document.querySelectorAll("#outter, #inner");
var finalArray = new Array();
for (var i = 0; i < firstNodelist.length; i++) {
var secondNodelist = firstNodelist[i].querySelectorAll("div");
var firstArray = new Array();
for (var x = 0; x < secondNodelist.length; x++) {
firstArray.push(secondNodelist[x]);
}
finalArray = finalArray.concat(firstArray)
}
console.log("FINAL", finalArray);
The jsfiddle exemple
Rather than building a second, unnecessary array within your loop, just use that inner loop to check whether the node is already in the array (Array#indexOf on all modern browsers) and only add it if it isn't.
var firstNodelist = document.querySelectorAll("#outter, #inner");
var finalArray = []; // `[]` rather than `new Array()`
for (var i = 0; i < firstNodelist.length; i++) {
var secondNodelist = firstNodelist[i].querySelectorAll("div");
for (var x = 0; x < secondNodelist.length; x++) {
// Get this node
var node = secondNodeList[x];
// Is it in the array already?
if (finalArray.indexOf(node) === -1) {
// No, put it there
finalArray.push(node);
}
}
}
console.log("FINAL", finalArray);
Be sure to test your target environment(s) to be sure they have Array#indexOf.
Having said that, there's a much better way for that specific situation: Live Example | Live Source
var finalArray = Array.prototype.slice.call(
document.querySelectorAll("#outter div, #inner div")
);
...since querySelectorAll won't include the same node more than once, even if #inner is inside #outter (or vice-versa). (The Array.prototype.slice.call(someObject) is a trick to get a true array from any array-like object.)
Related
I have this code in javascript
var variables = document.getElementsByClassName('highlight');
var array = [];
while(variables.length > 0){
array.push(variables[0].innerHTML);
//Variables 0th index must remove here
}
I want to remove 0th index of node list variables.
Similar to splice method in arrays.
Use shift() and be sure to convert the nodeList to an array
var nodeList = document.getElementsByClassName('highlight');
var variables = Array.prototype.slice.call(nodeList);//convert to array
var array = [];
while(variables.lenght > 0){
array.push(variables[0].innerHTML);
variables.shift();
}
demo
Use a regular old for loop:
var variables = document.getElementsByClassName('highlight');
var array = [];
while (var i = 0; i < variables.length; i++) {
array.push(variables[i].innerHTML);
}
In modern JS, one might use map instead:
function getInnerHtml(elt) { return elt.innerHTML; }
Array.prototype.map.call(variables, getInnerHtml);
How can I create a multidimensional array in JavaScript?
I have:
var m = 4;
for (var i = 0; i < m; i++){
groupsData.name_of_bar = [];
groupsData.name_of_bar[i]['a'] = data[i].a;
groupsData.name_of_bar[i]['ab'] = data[i].ab;
groupsData.name_of_bar[i]['de'] = data[i].de;
groupsData.name_of_bar[i]['gh'] = data[i].gh;
groupsData.name_of_bar[i]['xy'] = data[i].xy;
}
If I do:
groupsData.name_of_bar[0]
I get errors:
TypeError: Cannot read property '0' of undefined
TypeError: Cannot set property 'a' of undefined
What am I doing wrong?
JavaScript doesn't support multidimensional arrays per se. The closest you can come is to create an array where the values in it are also arrays.
// Set this **outside** the loop so you don't overwrite it each time you go around the loop
groupsData.name_of_bar = [];
for (var i = 0; i < m; i++){
// Create a new "array" each time you go around the loop
// Use objects, not arrays, when you have named properties (instead of ordered numeric ones)
groupsData.name_of_bar[i] = {};
groupsData.name_of_bar[i]['a'] = data[i].a;
groupsData.name_of_bar[i]['ab'] = data[i].ab;
groupsData.name_of_bar[i]['de'] = data[i].de;
groupsData.name_of_bar[i]['gh'] = data[i].gh;
groupsData.name_of_bar[i]['xy'] = data[i].xy;
}
Each iteration through the loop, you are doing groupsData.name_of_bar = [];. This removes whatever else is already in there and replaces it with a blank array.
Also, when you do groupsData.name_of_bar[i]['a'], you need to create groupsData.name_of_bar[i] first.
A way to do this is:
groupsData.name_of_bar = [];
var m = 4;
for (var i = 0; i < m; i++){
groupsData.name_of_bar.push({
a: data[i].a,
ab: data[i].ab,
ab: data[i].ab,
de: data[i].de,
gh: data[i].gh,
xy: data[i].xy,
});
}
Note that in JavaScript, arrays can only be numerically indexed. If you want string indexes, you need to use an object.
Also, if there are no other values in data[i], then you can simplify this even further by doing:
groupsData.name_of_bar = [];
var m = 4;
for (var i = 0; i < m; i++){
groupsData.name_of_bar.push(data[i]);
}
Heck, why not just use groupsData.name_of_bar = data; and lose the loop altogether?
The way you are declaring your objects are a little off. It looks like you are attempting to create an array of objects.
var groupsData = {name_of_bar: []},
m = 4,
i = 0;
for(; i < m; i++) {
groupsData.name_of_bar.push({
a: data[i].a,
ab: data[i].ab,
de: data[i].de,
gh: data[i].gh,
xy = data[i].xy
});
}
I have a javascript array of objects: each object contains key/value pairs. I'm trying to iterate through this array, and delete any object whose value for a particular key (say "Industry") fails to match a given value. Here is my code, for some reason it's not looping through the whole array, and I think it has something to do with the fact that when I delete an item the loop counter is botched somehow:
var industry = 'testing';
var i = 0;
for (i = 0; i < assets_results.length; i++) {
var asset = assets_results[i];
var asset_industry = asset['industry'];
if (industry != asset_industry) { assets_results.splice(i,1); }
}
Any ideas? Thanks in advance.
This is because when you splice one element, the size of array decreases by one. All elements after the splice shift one position to the beginning of the array and fills the space of spliced one. So the code misses one element.Try this code.
var industry = 'testing';
var i = 0;
for (i = 0; i < assets_results.length; i++) {
var asset = assets_results[i];
var asset_industry = asset['industry'];
if (industry != asset_industry) {
assets_results.splice(i,1);
i--;
}
}
This is a common problem when modifying an object while iterating through it. The best way to avoid this problem is, rather than deleting pairs from the existing array if they fail the test, to create a new array and only add pairs if they pass the test.
var industry = 'testing';
var i = 0;
var asset_results_filtered = [];
for (i = 0; i < assets_results.length; i++) {
if (industry == assets_results[i]) {
asset_results_filtered.push(assets_results[i]);
}
}
EDIT: Your code looked a bit illogical — I modified the example to use the variables given.
splice removes an element from an array and resizes it :
var arra = ['A', 'B', 'C', 'D'];
arr.splice(1,2); // -> ['A', 'D'];
Which means that you should not increment i when you splice, because you skip the next element. splicing will make of the i + 2 element the i + 1 element.
var industry = 'testing';
for (var i = 0, max = assets_results.length; i < max; ) { // Accessing a property is expensive.
if (industry != assets_results[i]['industry']) {
assets_results.splice(i,1);
} else {
++i;
}
}
Try this instead:
var industry = 'testing';
var i = assets_results.length - 1;
for (; i > 0; i--) {
var asset = assets_results[i],
asset_industry = asset['industry'];
if (industry != asset_industry) { assets_results.splice(i,1); }
}
http://jsfiddle.net/gfuKS/5/
var transitionInitial = {property: "none"};
var rules = ["color", "background-color"];
var transitions = [];
for ( var k = 0; k < rules.length; k++)
{
transitions[k] = transitionInitial;
transitions[k].property = rules[k];
alert(transitions[0].property);
}
Why at the second iteration transitions[0].property equals "background-color"?
Because you are storing a reference to transitionInitial, not a copy of it. transitionInitial points to an object in memory, and you are storing a reference to this object in transitions[k]. Regardless of the iteration you are at, you are always changing the same object.
It's because both values in your transitions array are pointing at the same object. During the execution of your code you produce one object that has three different references (transitionInitial, transistions[0], & transistions[1]).
During the first iteration of the loop, transistions[0] is set to reference the transitionInitial object. Then the property property of that object is set to the value "color". During the second iteration transitions[1] is set to reference the same object as transitionInitial and transitions[0]. You then reset the property's value to "background-color".
To solve this create different objects for each of your array indexes:
// Not needed anymore:
// var transitionInitial = {property: "none"};
var rules = ["color", "background-color"];
var transitions = [];
for ( var k = 0; k < rules.length; k++) {
transitions[k] = {};
transitions[k].property = rules[k];
alert(transitions[0].property);
}
Does it have anything with this to do maybe? for ( var k = 0; k < rules.length; k++)
Try changing the timer.
I have the length of my previous object and i need to create a new array of objects based on the length with new key's.
Length = 3;
var newArray = [];
for(var i =0; i <3; i++){
var Object = {};
Object['newKey'] = 1;
newArray.push(Object);
}
This would eventually create newArray of Objects whose length is 3 containing something like this.. newArray[0],[1],[2].
Am i doing this correctly, please do suggest me if anything wrong or a better way to do this.
Here's what you wrote (I think), just shortened a bit (and fixed the capitalization of variable names)
var length = 3;
var newArray = [];
for( var i = 0 ; i < length ; i++ ) {
newArray.push({newKey: 1});
}
but to be honest it's unclear to me exactly what you're trying to accomplish
You could make it slightly more dynamic by referencing the variable for length.
Example updated per comments:
var length = 3,
newArray = [];
for ( var i=0; i<length; i++ ) {
var tempObj = {};
tempObj['newKey'] = 'SomeValue';
newArray.push(tempObj);
}
I didn't really do more than clean up what you have.