Safe way to check if array element exists? - javascript

I have a 2D array.
I currently access that array using notation such as:
myArray[5][9] (for example).
What is the safest way to check whether or not a certain array element exists?
For example, let's say I am looping through the array and retrieving a property of each array element like so:
myArray[5][9].firstName
I then come to myArray[9][11].firstName (for example) which doesn't exist. Clearly this will throw an exception as the element doesn't exist.
How can I deal with this? I'm not looping through the entire array (i'm accessing it's contents randomly and say using myArray.lengthin a for loop will not work.
Is there a JS function / method for checking whether or not an array element exists?
Thanks.

Safe call operator ?. looks fine. Warning: many, but not all implementations (and versions) of JavaScript supports it.
For your example it will looks like
myArray[5][9]?.firstName
EDIT: Thanks to Asaf's comment there is safer version
myArray?.[5]?.[9]?.firstName

like
if (!('firstname' in myArray[i][j])) { ... }

Just check it with if condition.
if(myArray[i][j].firstName){
}

You can use the hasOwnProperty method to check if an array item exists:
if (myArray.hasOwnProperty(x) && myArray[x].hasOwnProperty(y)) {
var name = myArray[x][y].firstName;
}
This checks both dimensions. If you know that the first index (x in the example) is always inside the range, you can skip the first test.
If you store some other values in the array also, you would need to check if the item has the firstName property:
if (myArray.hasOwnProperty(x) && myArray[x].hasOwnProperty(y) && myArray[x][y].hasOwnProperty('firstName')) {
var name = myArray[x][y].firstName;
}

Related

find value in complex object javascript

Basically I have a complex object that retrieves the GPT API (google publisher tag) with this function:
googletag.pubads().getSlots();
The object value is something like this:
I need to know if there is a way to compare the value of each property with an X value without getting a problem of recursivity (because the object is huge and i need to to that validation several times)
Also, I tried to convert that object into a JSON with JSON.stringify(), and then tried to get the value with a regex, faster, but with this option, I have the problem with Cyclic Object Value.
Any suggestions ?
it's more simple. try it to convert it into an array and later use a filter for comparative with your value.
var objGoogle = {};
var arrayObjectGoogle = [objGoogle];
var filter = arrayObjectGoogle.filter(function(obj){
obj.yourAttr == yourValue; });
this will give you a second array with the values found it. later, index the array for pick up the value do you need.

In an Ember Array, how do i access object by index value? Ember Js

For an ember array you can simply do this:
array.get('firstObject');
to get the first object in array.
or this:
array.get('lastObject');
to get last object in array.
How do I get something by its index? similar to how it works in an ordinary javascript array:
array[index];
Looking at the documentation, you could just do var myObject = array.objectAt(someIndex);, and that will return the object at that specific index. You can check the documentation here.
array.get(index)
actually works. index can be either an integer or a string.
It also works for array-properties, ie.
this.get('myArray.1')
will return the second element in the myArray property.

Using javascript's indexOf on an array of svg text elements

I am working with an svg file which has a number of text elements within it. The text elements are all numbers. I am able to get the list of values and put them into an array with the following line of code.
var fretdata = document.getElementById("fretinformation").getElementsByTagName("text");
I am able to access .length property and also the access the array elements by index such as [0].textContent. However, when I try to use the .indexOf() function on the array, I receive an error message that the object (my array) does not support the property or method of indexOf.
I am able to setup a for loop to iterate through the array checking each value looking for the presence or absence of a certain value. I would like something with the simplicity of the indexOf functionality which tells me whether or not something is present within the array and where it is if present. Is there a to get .indexOf() working with the svg text element array? Or is there a similar alternative which does not require the use of loops and flags?
I think the problem lies in the fact that I have an array of text elements and not an array of strings. But I'm not sure how to directly get the array of the text element's textContent
var fretdata = document.getElementById("fretinformation").getElementsByTagName("text");
//var fretdata = document.getElementById("fretinformation").getElementsByTagName("text").textcontent;
//18th fret is the upper fret limit
//0 fret (open string) is the lower fret limit
//var zerolocation=fretdata.indexOf("0");
for (fd=0;fd<fretdata.length;fd++){
if(fretdata[fd].textContent=="0"){
document.getElementById("downkey").setAttribute("onclick",null);
document.getElementById("downkey").getElementsByTagName("polygon")[0].style.fill="#D3D3D3";
}
}
Iterating in the loop works. The two lines commented out using the .indexOf do not.
Thanks, --christopher
What you have is not an array, it's a nodeList.
A nodeList has length, and is array-like, but array methods like indexOf, forEach etc. doesn't work on nodeLists.
You can convert a nodeList to an array like this
var array = Array.prototype.slice.call(fretdata);
but in your case you really shouldn't, you should stick to the iteration instead.
Iterating the elements is really an option, but if you don't like it, you may have 2 more options depending on your setup:
The following code requires map function (check compatibility here, it basically requires IE9+) and slice function compatibility (same, IE9+).
var fretdata = document.getElementById("fretinformation").getElementsByTagName("text");
alert([].slice.call(fretdata).map(function(o) { return o.textContent; }).indexOf("1"));
The other one requires jQuery, it handles a lot of stuff for you.
alert($( "#fretinformation > text" ).filter(function() { return $(this).text() === "1"; } ).length);
use ES6 spread operators
var fretdata = [...(document.getElementById("fretinformation").getElementsByTagName("text"))]
This internally works as
var array = Array.prototype.slice.call(fretdata);

best way to append an item to a list within a JSON object?

I'm working on JavaScript and I have this JSON object:
var obj ={"name" : "objName",
"dynamicList" :[]};
and then I add some items to my list like this:
obj.dynamicList["someStringID"] = {"watever"};
It's important that I use a string as indexer for each item on my list (i didn't know this could be done until recently).
My only problem now is that whenever I ask for obj.dynamicList.lenght I get 0, unles I manually set the proper number... I was wondering if there's a better way to add items to my list?
Thanks!!
In Javascript, string index is not really an index. It's actually an attribute of the array object. You could set and get the value with the string index, but it's actually an empty array with some attributes. Not only .length, but also .sort(), .splice(), and other array function would not work. If there is a need to use array functions, I would use number as an index to make it a real item in the array.
If you have to use the string as an index, you couldn't rely on .length function. If there is no need to support IE prior to version 9, the Object.keys as suggested by #strimp099 should work. or you may have to create function to count the number of attributes for example:
function len(obj) {
var attrCount = 0;
for(var k in obj) {
attrCount++;
}
return attrCount;
}
and then call
len(obj.dynamicList);
Use the following the find the length of dynamicList object:
Object.keys(obj.dynamicList).length
To do this "the right way," you will have to make obj.dynamicList an object instead of an array; use {} instead of [] to set the initial value.
How to efficiently count the number of keys/properties of an object in JavaScript?
dynamiclist is an object, the length is not the length property you expect from an array.

Checking if an element exists in json

using the following feed:
http://api.twitter.com/1/statuses/user_timeline.json?screen_name=microsoft&include_rts=1&count=10
I am successfully able to loop through this to get the details I want to display on my html page.
However, I need to check if retweeted_status.user.profile_image_url exists, and I am not sure how to do that?
Currently I am looping through the data where data is returned by jquery-ajax:
data[i].retweeted_status.user.profile_image_url
if data[i].retweeted_status.user.profile_image_url does not exist, it does not return null or undefined, I just get the following error:
cannot read property 'user' of undefined
That error message suggests that either your data[i] or your retweeted_status is undefined, which means your call to get the json is most likely failing. WHen data is returned from Twitter it will aways have a profile image url, because they show an egg-like image for those with none uploaded. You should put this before your for loop:
if (typeof(retweeted_status) != "undefined")
{
//code for what to do with json here
}
I think it's a good answer:
if('key' in myObj)
if (something !== undefined) {
...
}
... or even better:
if (typeof something != "undefined") {
...
}
If you are looping and accessing nesting objects:
if(!data)
return;
while(data.length)
{
var tweet_data = data.shift();
/* do some work */
if(!tweet_data|| !tweet_data.retweeted_status)
continue;
var retweeted_status = tweet_data.retweeted_status;
/* do your other work */
}
This loop no longer needs to use array indexes, which isn't the most efficient unless you specifically need the index for something. Instead, it pops the first element off the array and using that object directly. The loop internals can then check the existence of a property on tweet_data.
I try to avoid using more than 1 level of dereferencing for 2 reasons (like objA.child.property):
1) You can check the existence of an object from the start and if it doesn't exist, jump out or assign default values.
2) Everytime JavaScript needs to access the method property, it first has to find child withing objA and then access property. Could be slow in large loops.
Take a look at $.grep(). It helps you loop through JSON objects. I used it on the link you provided. I used it to loop through the tweets and find the retweeted user images. You can have a look at my code here:
http://jsfiddle.net/q5sqU/7/
Another thing you can do, which has worked for me:
if(retweeted_status) {
// your code
}

Categories

Resources