How to access array within an object within an array? - javascript

I have both an object and an array:
var elementsArr = [];
var elements = {
polygon: 734,
infoContent: "huhu",
id: 0
}
I am going to have multiple "elements" and push each one into "elementsArr".
for(var i=0; i<20; i++){
elements.id = id +=1;
elementsArr.push(elements);
}
My problem now is how to access a specific "id" within the object elements, within the array elementsArr and pushing this into another array.
I tried this but it doesn't seem to be working:
var ids = [];
for(var m=0; m<elementsArr.length; m++){
if(elements.id == elementsArr[m]){
ids.push(elements.id);
}
How do I do this?

Your code is pushing the same object onto the array over and over again.
One way to fix that would be to write a function to get a new element:
function Element(id) {
return {
polygon: 734,
infoContent: "huhu",
id: id
};
}
for(var i=0; i<20; i++){
elementsArr.push(Element(i));
}
If there are going to be a lot of elements, and the "id" values are all relatively small numbers, you'd be better off storing the elements such that the "id" is also the index:
for (var i = 0; i < 20; i++)
elementsArr[i] = Element(i);
To get the element with "id" 17, then:
var element17 = elementsArr[17];
If you really want to search, however, you can use .find():
var element17 = elementsArr.find(function(elem) { return elem.id === 17; });
or a simple loop:
for (var i = 0; i < elementsArr.length; ++i) {
if (elementsArr[i].id === 17) {
// found it!
}
}
You can extract the "id" values from the array with a simple call to .map():
var ids = elementsArr.map(function(elem) { return elem.id; });
or another for loop:
var ids = [];
for (var i = 0; i < elementsArr.length; ++i)
ids.push(elementsArr[i].id);

There are a couple of ways to do this. If you are able to work in ES6 then a WeakMap would be great.
However, I'm going to give you an ES5 instead.
Option 1 Loop through the data.
If you aren't accessing the data often, then looping through as you've done so may be the best choice.
Option 2 Set up your own index
On the other hand, if you need faster lookup, you can set up your own separate index to look things up.
var elementsLookup = {}; // Create an empty object.
for(var i=0; i<20; i++){
elements.id = id +=1;
elementsLookup[id] = elements; // Stash off a copy
elementsArr.push(elements);
}
Then you can look things up with a
var elem = elementsLookup[2]; // Get the element with an id of 2.

It is easy to do it with Array prototyping. Here is a function findById
Array.prototype.findById = function(id){
for(var x = 0 ; x < this.length; x++){
if(this[x].id == id){
return this[x];
}
}
return false;
}
You can use this function to recieve any id from the array or false if it does not exists
elementsArr.findById(17);

Related

How to loop through an array of 100 objects with different properties and retrieve 1 property value from each?

I have an array of 100 objects with different properties in each object. I am trying to do a for loop through the array to get 1 particular property from each object and push it to a new array. I've tried:
for (var item in response.data) {
main.allUsers.push(item);
}
And when I console.log(main.allUsers); I get an array that looks like ["0","1", "2", "3", "4"...] .
When looping through an object properties, the left-side of the for...in loop is a string that represents the current object's property name. So, you must use the notation object['property'] to get the correspondent value of that property. You should be using:
main.allUsers.push(response.data[item]);
Although, it seems your response.data is an Array, not an object, so, you shouldn't be using for...in at all, since it was designed to loop through object properties.
When looping through an Array, you should be using the regular for loop, or you can use the Array.prototype.forEach loop, which will iterate similar to the way your trying with for...in. When ES6 be fully supported, you'll be able to use the for...of loop, that's similar to what you're trying:
for (var i = 0; i < response.data.length; i++) {
var item = response.data[i];
main.allUsers.push(item);
}
// or
response.data.forEach(function(item, i) {
main.allUsers.push(item);
}
// and in the future (it already works in Firefox, if you wanna give a try)
for (var item of response.data) {
main.allUsers.push(item);
}
Update
Answering to your comment, you could be using:
response.data.forEach(function(item) {
main.allUsers.push(item.DisplayName);
});
// or
for (var i = 0; i < response.data.length; i++) {
main.allUsers.push(response.data[i].DisplayName);
}
// or if you don't have any items inside main.allUsers yet
main.allUsers = response.data.map(function(item) { return item.DisplayName; });
Using javascript you could also do the following.. Jsfiddle
var arrayOfObjects = [
{name: "myName1",
age: 12
},
{surname: "mySurname2",
age: 26
}
//98 more...
];
var myData = [];
for(var i = 0; i < arrayOfObjects.length; i++){ //iterate array of objects
for(var key in arrayOfObjects[i]){ //iterate each object key
if(arrayOfObjects[i].hasOwnProperty(key) && key == "age"){
//make sure its the key you want
myData.push(arrayOfObjects[i].age);
}
}
}
console.log(myData);
To get each object in an array, you have to use
for(var i=0; i < response.data.length; i++){
var obj = response.data[i];
}
And now to get each property of object,
for(var i=0; i < response.data.length; i++){
var obj = response.data[i];
for (property in obj){
console.log(property);
}
}
Don't use for..in with arrays https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/for...in#Array_iteration_and_for...in. Use forEach, or standard for, or map. Like:
var _len = response.data.length;
for (var i = 0; i < _len; i++) {
main.allUsers.push(response.data[i]);
}

Speed of looping through an array vs. looping through an object

I'm not sure if this has been asked already, if it has, let me know in the comments and I'll delete the question. What's faster, looping through an object or looping through an array? For instance, if I have two arrays that are the exact same length(required for the script to run properly, not gonna get into details), each position in one array is associated with a position in the other array. So it looks like this:
var array_variable = ["get_ped_bridges", "get_rail_bridges"];
var array_url = ["http://eg.com/rest/services/Nope/MapServer/1", "http://eg.com/rest/services/Nope/MapServer/2"];
for(var j = 0; j < array_variable.length; j++){
console.log(array_variable[j], array_url[j]);
}
So as you can see, each url matches up to a position in the array_variable array. In an object, it would look something like this:
var object = {
one: {
variable: "get_ped_bridges",
url: "http://eg.com/rest/services/Nope/MapServer/1"
},
two: {
variable: "get_rail_bridges",
url: "http://eg.com/rest/services/Nope/MapServer/2"
}
}
So, if the lengths of both were substantially longer(the actual length would probably be around 20 positions), which loop would process faster?
The short answer is that generally an array is faster.
This is because of continuos indexing in an array, where it is always exactly known where the next element is (because it's stored contiguously)
you can refer to this previous answer for more info: Array vs. Object efficiency in JavaScript
<script src="http://broofa.com/Tools/JSLitmus/JSLitmus.js"></script>
<script>
JSLitmus.test('Array', function() {
var array_variable = ["get_ped_bridges", "get_rail_bridges"];
var array_url = ["http://eg.com/rest/services/Nope/MapServer/1", "http://eg.com/rest/services/Nope/MapServer/2"];
for (var j = 0, len = array_variable.length; j < len; j++) {
//
}
for (var j = 0, len = array_url.length; j < len; j++) {
//
}
});
JSLitmus.test('Object', function() {
var object = {
one: {
variable: "get_ped_bridges",
url: "http://eg.com/rest/services/Nope/MapServer/1"
},
two: {
variable: "get_rail_bridges",
url: "http://eg.com/rest/services/Nope/MapServer/2"
}
};
for (var i in object) {
//
}
});
</script>

JavaScript for loop closure issue

I am adding all categories after ticking them to true if they exists in selected categories of result but it combines previous categories results with current one. I tried closure but it doesn't give me fresh object. Check out fiddle.
var allCatsResult = [{"id":1},{"id":2}, {"id":3}, ... ];
var catsArray = [1, 2] // Array of ids from allCatsResult
var result = [
{"id":1, selectedCategories:[{"id":1},{"id":2}]},
{"id":2, selectedCategories:[{"id":4},{"id":5}]},
...
];
for (var i = 0; i < results.length; i++) {
var tmp = allCatsResult; // tried to add function form here didn't work
for (var k = 0; k < results[i].selectedCategories.length; k++) {
var index = catsArray.indexOf(results[i].selectedCategories[k].category_id);
if(index !== -1) {
tmp[index].ticked = true;
}
}
results[i].categories = tmp;
}
Above code gives combined result for ticked = true for all categories in each result.
You need to copy/clone the array of objects, or you're manipulating the original. There are a few ways apparently. I chose the following:
var tmp = JSON.parse(JSON.stringify(allCatsResult));
This will create a new array of objects in tmp, and it will correctly only modify the clone.

Setting vars using for loops

I have the following javascript
information0 = xmlDoc.getElementsByTagName("info")[0].textContent;
information1 = xmlDoc.getElementsByTagName("info")[1].textContent;
information2 = xmlDoc.getElementsByTagName("info")[2].textContent;
information3 = xmlDoc.getElementsByTagName("info")[3].textContent;
information4 = xmlDoc.getElementsByTagName("info")[4].textContent;
information5 = xmlDoc.getElementsByTagName("info")[5].textContent;
information6 = xmlDoc.getElementsByTagName("info")[6].textContent;
I want to create a new var for each index number. There are 600 in total. How can I do this using a for loop?
Thanks in advance
The best thing here is to use an array, not a bunch of individual variables.
var information = [];
var index;
var info = xmlDoc.getElementsByTagName("info");
for (index = 0; index < info.length; ++index) {
information[index] = info[index].textContent;
}
Um... use an array? Also, don't call getElementsByTagName repeatedly, it's expensive!
var tags = xmlDoc.getElementsByTagName('info'), l = tags.length, i, information = [];
for( i=0; i<l; i++) information[i] = tags[i].textContent;
If you're in a reasonably up-to-date browser:
var information = [].map.call(xmlDoc.getElementsByTagName('info'),function(a) {return a.textContent;});
Like this:
var information = [],
i,
elements = xmlDoc.getElementsByTagName("info"),
n = elements.length;
for (i = 0; i < n; ++i) {
information[i] = elements[i].textContent;
}
You need to use an array.
var infoTags = xmlDoc.getElementsByTagName("info"),
i = 0,
len = infoTags.length,
values = []; //array literal syntax, you could also use new Array()
for (; i < len; i++) {
values.push(infoTags[i].textContent); //push the textContent into the array
}
Things that you should note:
I cached the result of getElementsByTagName instead of performing the query multiple times.
I cached the length property of infoTags. That avoids multiple property lookups to access infoTags.length on every iterations. Property lookups are expensive in JavaScript.
To know how you can work with arrays, have a look at the Array object.
-

Push is not a function JavaScript error

In the below code, I am getting "push is not a function" error. Can anyone please let me know what I am doing wrong here? I am trying to create 2D array in Javascript.
var myArray = new Array(4);
myArray = ["0","0","0","0"];
for (var i=0; i<myArray.length; i++) {
myArray[i].push("ID");
myArray[i] = new Array(1);
for (var j=0; j<myArray[i].length; i++) {
myArray[i][j].push("Array[j]");
}
}
Firebug is pointing me to:
myArray[i].push("ID");
For this line I am getting "TypeError: myArray[i].push is not a function"
Final array it should look like is:
[ID,"SomeValue1"],
[ID,"SomeValue2"],
[ID,"SomeValue3"]
And I cannot hard code, I need to create this dynamically based on data from DB
myArray[i].push("ID");
Is invalid of course because it's a function defined for an Array not for it's elements.
valid syntax would be
myArray.push("ID");
To know more about array.push() go here.
This will create your example.
var myArray = new Array(4);
for (var i = 0; i < myArray.length; i++) {
myArray[i] = ["ID", "SomeValue" + (i+1)];
}
But if you need to set data from a database, how is that being set in the Javascript? if it's in a different array you could do the following:
var dbArray = ["SomeValue1", "SomeValue2", "SomeValue3"];
var myArray = new Array(dbArray.length);
for (var i = 0; i < myArray.length; i++) {
myArray[i] = ["ID", dbArray[i]];
}
First of all, you can initialize Arrays using the Array Literal [] which should always be preferred
Then push is an Array method. So you have to call it on an Array
myArray[i] is the Element of the Array, myArray the Array
var arr = [];
for (var i = 0; i < 5;i++) {
arr.push = []; //Uses the Arrays push method
for ( var j = 0; j < 5; j++)
arr[i][j] = "Asd"; //Sets an Element
}
console.log(arr);
And as you see don't need to "Dim" an Array, you just can assign an Array to a Variable and start pushing Elements in it.
As you can see in the example, the first time
push is directly after arr, its the Arrays Method and appends a new Element to the Array
And in the second Example it accesses the Element and assigns it a value directly
What you are doing in your code is trying to invoke the push method on an Elements Array
Assume i is 0 Then
'myArray[i]' is "0" and the String "0" has no Method push.
But you can directly assing a new String to the Element like.
myArray[i] = "ID"

Categories

Resources