I have a large array called "data".
At the 10th array position i have this at its data value:
[10] => 1,2
Now what im trying to do in JS is something like this:
i = 1;
if(i in data[10]){
//great success, very nice!
}
I thought comma separated data might act like an array with the "IN" method, but its not working. I get this error:
Uncaught TypeError: Cannot use 'in' operator to search for '1' in 1,2
What would be the correct solution for my problem ?
You don't show the code for how you assign 1,2 to data[10]. The value of 1,2 is simply 2 as you can see from executing the following in a JavaScript shell/console. See the reference for how the comma operator works.
However, the error message you are getting suggests that you have the string"1,2". To turn it into an array, you should use split() as in:
> data[10] = "1,2"
1,2
> data[10].split(',')
[ "1", "2" ]
To iterate over the values you can use the in operator on the resulting Array as in:
var data = new Array();
data[10] = '1,2';
var valueArray = data[10].split(',');
for (var i in valueArray) {
alert('valueArray[' + i + '] is ' + valueArray[i]);
}
You can run this in a browser console and the alert will show you two messages:
valueArray[0] is 1
valueArray[1] is 2
Note that you don't need to initialize i before the loop begins. The inoperator will do this automatically. Also, it's good practice to use local variables hence the var i in the code above.
On a side note, if you are new to JS but you need to deal with a lot of data structure manipulation, it's worth learning about underscore.js. Take a look at _.each() in particular. Underscore can save you from writing a lot of looping logic.
If, however, you want to do a membership check then you need to use not in but Array.indexOf(). See http://jsfiddle.net/nRS9m for an example forked from your jsfiddle in the comments. More examples:
> valueArray
[ "1", "2" ]
> valueArray.indexOf("3")
-1
> valueArray.indexOf("1")
0
> valueArray.indexOf("2")
1
> valueArray.indexOf(1)
-1
> valueArray.indexOf((1).toString())
0
Related
I'm trying to push an array (multiple times) into another array. Instead of an array of arrays, I'm getting all the values from the multiple push attempts as a single array. I've tried pushing an array implicitly (i.e. push([val1,val2]), explicitly creating a new Array, then pushing the new Array. Here's the key part of the code:
var coordinates=[];
...
for(i=0;i<6;i++)
{
...
for(var j=start;j<circum[i].length;j++)
{
var segmentCoords=[];
...
if(segmentFlag===false)
{
segmentCoords.push([i+1,segmentLength]);
segmentFlag=true;
}
...
if(segmentFlag===true)
{
var tempArray=new Array(i+1,segmentLength);
segmentCoords.push(tempArray);
segmentLength+=sectorLength;
coordinates.push(segmentCoords);
segmentFlag===false;
}
...
}
From the many stackoverflow questions/answers I've looked at, I expect my coordinates array to look something like this: [[val1, val2],[val3,val4],[val5,val6]]. Instead it's [val1,val2,val3,val4,val5,val6]. That is what I would expect if I were using .concat() or .apply().
Can anyone explain why my code isn't generating an array of arrays?
I've got the full code here https://jsfiddle.net/Seytom/7xm9s4qr/ in case you want to see more of it.
You seem to be fooled by your console.log. Notice the difference between these two statements:
console.log( 'string ' + [[1,2],[3,4]] ); // string, '1,2,3,4'
console.log( 'string ', [[1,2],[3,4]] ); // string, [[1,2],[3,4]]
Because you are coercing the array into a string, this is the result. Its the same as:
console.log( new Array([1,2],[3,4]).join(',') ); // 1,2,3,4
It's simply what arrays do when you join them, regardless of whether they are nested. It is better to log the array separately so you can explore it in your console, so simple print your string and then add the array as the second argument. (The console takes an infinite amount of arguments and will print them all as one statement - safari even prints the first as a special type if its a string so its clearer to read).
In short: push behaves exactly as expected, and your code should simply work as intended, but the printing to the console seems to leave a bit to be desired :).
Use Array.concat:
var arrA = [0];
var arrB = [1, 2];
while (arrA.length < 10) {
arrA = arrA.concat(arrB)
}
console.log(arrA)
"abc":[{"a":"a"},{"b":"b"},{"c":"c"}];
I got this from my ajax's data callback, how can I know there's 3 object in it? I tried .length method but it grave me the wrong number.
Using .length on the array will give you the correct answer 3, but most likely you're doing data.length which is wrong in your case.
data["abc"].length will yield correct result.
Use Below code you will get 3 in console :
<script>
var test = {"abc":[{"a":"a"},{"b":"b"},{"c":"c"}]};
console.log("Length :"+test.abc.length);
</script>
It doesnt matter if you have objects in your array or other elements, array.length always works on it.
Readup: Array.length - JavaScript | MDN
The code that you have posted, it looks like abc is a property of an object.
var obj = {
"abc":[{"a":"a"},{"b":"b"},{"c":"c"}] // semicolon removed
};
alert(obj.abc.length); // compute length/number of objects here
Array.length will give you the number of elements in the array.
Your example
([{"a":"a"},{"b":"b"},{"c":"c"}].length == 3) // => true
So your issue lies elsewhere.
Server side code
$NATIVE_TEST_TEMPLATE_IDS = array(145);
Client side code to assign PHP array into javascript -
var nativetestTemplates = "<?php echo json_encode($NATIVE_TEST_TEMPLATE_IDS); ?>"; //PHP array into JSON.
But now, the JSON object nativetestTemplates that I have here does not look ready for doing Object instance checks. I need to check if, say, 145 exists in the object nativetestTemplates.
Following are details of console log -
nativetestTemplates.length -> 5
Also, the individual elements of the array have the following -
nativetestTemplates[0] -> [
nativetestTemplates[1] -> 1
nativetestTemplates[2] -> 4
nativetestTemplates[3] -> 5
nativetestTemplates[4] -> ]
So, what did I do wrong and what is the best method to check if an element exists in the object.
Update
After fixing mistake pointed out by Djave, I am still having problem checking if an element exists in the object nativetestTemplates.
Here is my code -
Case 1
var testAdnetworkId = $("#adnetwork_type").val(); //reading selected dropdown value
console.log("see "+$.inArray(testAdnetworkId, nativetestTemplates)+" and "+nativetestTemplates[testAdnetworkId]);
This returns following even when testAdnetworkId has a matching value -
see -1 and undefined
Case 2
But, if I do this -
var testAdnetworkId = 145; //hardcoded integer val
I get the desired output for $.inArray check -
see 0 and undefined
console.dir of testAdnetworkId in case 1 gives this -
0 "1"
1 "4"
2 "5"
However in case 2, it gives -
0 145
Can, someone please explain the proper way to do object property check in Case 1 (reading value of select dropdown)
Don't wrap it in quotes, you are saying
var nativetestTemplates = "[145]";
you want it to say
var nativetestTemplates = [145];
So, your code would read:
var nativetestTemplates = <?php echo json_encode($NATIVE_TEST_TEMPLATE_IDS); ?>; //PHP array into JSON.
The reason that you are getting the weird output ([, 1, 2 etc) is that Javascript is just finding the character 0, 1, 2 characters from the start of the string, rather than the item at the start of the array.
Edit
Funnily enough its the same issue, you are muddling up your variable types again. Because you are getting the val() of (I imagine) an input field, you are looking for a string again.
console.log(typeof($("#adnetwork_type").val())); // Logs 'string'
Don't fret though, you can fix this.
var testAdnetworkId = parseInt($("#adnetwork_type").val()); //reading selected dropdown value
parseInt() is your friend. It tries its best to replace a string or other variable with a number, which is what you want. You will see here http://codepen.io/EightArmsHQ/pen/Kjgfh that it works.
More on variable types:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Values,_variables,_and_literals
you need to parse json variable in javascript as following:
nativetestTemplates = JSON.parse(nativetestTemplates);
Now nativetestTemplates.length will give you correct result.
First I am sorry because this possibly will be very simple. But I work a lot in PHP, but that syntax won't work in JS.
I've got the following pieces of code:
var rangeArr = [];
// This piece is inside an loop of adding elements...
rangeArr[row_id] = {"row_x": row_x, "row_y": row_y, "row_name": row_name, "row_dir": row_dir, "row_length": row_length, "row_height": row_height};
row_id++;
I'll get this object for instance (got from Chrome console):
rangeArr
[undefined × 1,
Object
row_dir: "lr"
row_height: "6"
row_length: "5"
row_name: ""
row_x: 45
row_y: 71
__proto__: Object
,
Object
row_dir: "lr"
row_height: "6"
row_length: "6"
row_name: ""
row_x: 95
row_y: 208
__proto__: Object
]
I'm using the following piece of code to loop through the object array:
for (var item in rangeArr) {
if(typeof(item) !== 'undefined'){
console.log(item.row_x);
}
}
But I only get undefined errors... When I look into the console log, the whole item contains only the row_id. That means that only the index is retrieved, not the object itself.
As I said before, I have got little to no knowledge about JS Objects, but I thought that this was the right way to do this.
So how can I get my piece of code working so that I can receive the data when needed?
In your for in loop, item is actually the array key, not the array element value. To get the object, use rangeArr[item].
for (var item in rangeArr) {
var obj = rangeArr[item];
if(typeof(obj) !== 'undefined'){
console.log(obj.row_x);
}
}
That said, for in loops are a bad idea on arrays. A basic incremental for loop, or a forEach is preferred. Refer to this question for more info.
It looks like you're generating the incremental keys manually. Instead of that, you might prefer to use Array.prototype.push():
rangeArr.push({"row_x": row_x, "row_y": row_y, "row_name": row_name, "row_dir": row_dir, "row_length": row_length, "row_height": row_height});
I have an array like:
errors = [ {...}, {...}, {...} ]
It's an instanceof array, yet it only returns 1 for .length?
Relevant code:
if(data.error){
errors.push({'element':ele,error:data.error});
}
//Above is looped a few times and there are N number of errors now inside
console.log(errors) //Returns 2+ objects like {...}, {...}
console.log(errors.length) //Returns 1
For Uzi and Muirbot, here's the errors array:
[
Object
element: b.fn.b.init[1]
error: "You must enter "example" into the field to pass"
__proto__: Object
,
Object
element: b.fn.b.init[1]
error: "Crap!"
__proto__: Object
It is correct, this code:
var errors = new Array();
errors.push({'element':'ele', error:'data.error'});
...adds ONE object to the array. The object has two properties.
It's possible your code is executing in an order other than what you're expecting. ie, when you log both errors and errors.length, errors does contain only 1 object. But after that you are adding to the errors array, and only after that are you looking at the console. At that point you could see a larger array in errors for two reasons - first, your actual code isn't logging errors but some object that contains errors. In that case the console display is live, and will show you not what was in errors at the time, but what is in it now. Alternatively, the console could just be taking some time to log errors.
Without more code I can't be sure if this is the case. But you could verify it by replacing console.log(errors); with console.log(errors[1]);. If errors is really only 1 long at the time, it will log undefined.
The problem was that Chrome's Web Inspector's console.log is an async event. So, the length was a property lookup so it gave that back instantly, but the object with two items inside was held off until the rest of the events had fired.
In the future I, and others with this issue, should use debugger; instead.
is it an Array object or something that resembles it?
arrays do work:
> a = [{a:1}, {b:2}]
[Object, Object]
> a.length
2
you'll have to provide more code.
and now that you've provided the relevant code, the correct answer is what Steve Wellens said (which was downvoted, by the way).
Array.push adds a single element, objects may have more than one key but they're still a single object so your real case was different from your original example, which of course works.
another possibility:
> a = []
[]
> a.length = 2
2
> a
[]
> a.length
2
> a instanceof Array
true