I keep getting eluded by how property values should be properly retrieved from array literals.
Object literal:
var obj = {
"p1": "v1",
"p2": "v2",
"p3": "v3"
};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key + " -> " + obj[key]);
}
}
Console log output:
p1 -> v1
p2 -> v2
p3 -> v3
Array literal:
var obj = [
{ "pa":"va1", "pb":"vb1" },
{ "pa":"va2", "pb":"vb2" },
{ "pa":"va3", "pb":"vb3" },
{ "pa":"va4", "pb":"vb4" }
];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key + " -> " + obj[key]);
}
}
Console log output (duh!):
0 -> [object Object]
1 -> [object Object]
2 -> [object Object]
3 -> [object Object]
What I'm trying to do: check if a string matches one of the pa values. If it does, do something.
This would be the logic:
var myString = "a value I'm getting from somewhere else ;)"
if (myString == any of the pa values) {
// do something
}
Any help appreciated!
Using the filter method (link contains code to add functionality to older browsers - IE8 and older) and then check the length of the resulting array:
var obj = [
{ "pa":"va1", "pb":"vb1" },
{ "pa":"va2", "pb":"vb2" },
{ "pa":"va3", "pb":"vb3" },
{ "pa":"va4", "pb":"vb4" }
];
var filtered = obj.filter(function(element) {
return element.pa === myString;
});
if (filtered.length > 0) {
// contains string
}
JS Fiddle
obj is not a object as you expect, it's an array of objects. You'll need to iterate the array and then iterate the keys in each array item.
var i, key;
for (i = 0; i < obj.length; i++) {
for (key in obj[i]) {
if (obj[i].hasOwnProperty(key) {
console.log(key + " -> " + obj[i][key]);
}
}
}
If you don't need to know the parent, there may be a performance boost in not looping through it all (depending on array and object sizes). This will also remove the need to change your code if another nested level of objects is added.
JSON.stringify(obj).indexOf(':"pa1"')>-1
JSON.stringify() turns your array into a string like this:
"[{"pa":"va1","pb":"vb1"},{"pa":"va2","pb":"vb2"},{"pa":"va3","pb":"vb3"},{"pa":"va4","pb":"vb4"}]"
Which we can then of course just do a normal textual search through
JSON.stringify() is supported for IE8 and above
This may be oversimplifying, but if you just want to know if you have a string in mystring that is an item in the array, the array can be addressed as indexed by strings.
Update - I ran this through firebug and discovered I had my notation incorrect for this method to work the way I thought it should - namely as a referable list of objects or values by label.
var obj = [];
obj["val1"] = "pa";
obj["val2"] = "pb";
mystring="val1";
if (obj[mystring]){
alert ('object exists in array');
}
else{
alert('object with index ' + mystring + ' does not exist');
}
No looping required, though your array setup has to change to support this sort of "look up" approach.
Related
I'm attempting to "loop" through an object and grab the name if a certain test passes.
For instance
var x = {
'first':[
'ab',
'abc',
],
'second':[
'sia',
'sss'
],
'third':[
'jp',
'jh'
]
};
As you can see, I have an object containing arrays.
Let's say that I am given the value "sss" .... I am trying to figure out how to get Javascript to output "second" when given the appropriate value.
The same goes for the following scenarios
third for jp
third for jh
first for abc
and so on.
One possibility (where x is your object, and y is your desired array value):
function foo(y) {
for (key in x) {
if (x[key].indexOf(y) > -1) {
return key;
}
}
}
This will find the first key that has the value you are searching for in its array
function myFunction(searchValue, myObject){
for(var i in myObject){
if(myObject.hasOwnProperty(i) && myObject[i].indexOf(searchValue) != -1){
return i;
}
}
}
You know what. No sooner I click Submit Question, did I realized how to do it.
var x = {
'first':[
'ab','abc',
],
'second':[
'sia','sss'
],
'third':[
'jp','jh',
]
};
for(var arr in x) {
var theArr = x[arr];
if(theArr.indexOf("sss") !== -1) console.log(arr) // returns "second"
}
And if you want to exclude properties in the prototype chain use the hasOwnProperty function:
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
console.log('property: ' + property + ' value: ' + obj[property]);
}
}
The in operator will traverse the prototype chain and return all properties in the object.
var x = {
'first':[
'ab',
'abc',
],
'second':[
'sia',
'sss'
],
'third':[
'jp',
'jh'
]
};
var result = Object.keys(x).filter(function(key) {
return x[key].indexOf('sss') > -1;
});
Afterwards, result will be an array containing all keys that contain the value sss, so it could be 0, 1 or more, if duplicates exist.
I have an js object like
{
a: 1,
b: 2,
c: 3
}
I wanted to stringify the above object using JSON.stringify with the same order. That means, the stringify should return me the strings as below,
"{"a":"1", "b":"2", "c":"3"}"
But it is returning me like the below one if my js object has too many properties say more than 500,
"{"b":"2", "a":"1", "c":"3"}"
Is there any option to get my js object's json string as in sorted in asc.
If the order is important for you, don't use JSON.stringify because the order is not safe using it, you can create your JSON stringify using javascript, to deal with string values we have 2 different ways, first to do it using regexp an replace invalid characters or using JSON.stringify for our values, for instance if we have a string like 'abc\d"efg', we can simply get the proper result JSON.stringify('abc\d"efg'), because the whole idea of this function is to stringify in a right order:
function sort_stringify(obj){
var sortedKeys = Object.keys(obj).sort();
var arr = [];
for(var i=0;i<sortedKeys.length;i++){
var key = sortedKeys[i];
var value = obj[key];
key = JSON.stringify(key);
value = JSON.stringify(value);
arr.push(key + ':' + value);
}
return "{" + arr.join(",\n\r") + "}";
}
var jsonString = sort_stringify(yourObj);
If we wanted to do this not using JSON.stringify to parse the keys and values, the solution would be like:
function sort_stringify(obj){
var sortedKeys = Object.keys(obj).sort();
var arr = [];
for(var i=0;i<sortedKeys.length;i++){
var key = sortedKeys[i];
var value = obj[key];
key = key.replace(/"/g, '\\"');
if(typeof value != "object")
value = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
arr.push('"' + key + '":"' + value + '"');
}
return "{" + arr.join(",\n\r") + "}";
}
The JavaScript objects are unordered by definition (you may refer to ECMAScript Language Specification under section 8.6, click here for details ).
The language specification doesn't even guarantee that, if you iterate over the properties of an object twice in succession, they'll come out in the same order the second time.
If you still required sorting, convert the object into Array apply any sorting algorithm on it and then do JSON.stringify() on sorted array.
Lets have an example below as:
var data = {
one: {
rank: 5
},
two: {
rank: 2
},
three: {
rank: 8
}
};
var arr = [];
Push into array and apply sort on it as :
var mappedHash = Object.keys( data ).sort(function( a, b ) {
return data[ a ].rank - data[ b ].rank;
}).map(function( sortedKey ) {
return data[ sortedKey ];
});
And then apply JSON.stringy :
var expectedJSON = JSON.stringify(mappedHash);
The output will be:
"[{"rank":2},{"rank":5},{"rank":8}]"
Here's my json:
{"d":{"key1":"value1",
"key2":"value2"}}
Is there any way of accessing the keys and values (in javascript) in this array without knowing what the keys are?
The reason my json is structured like this is that the webmethod that I'm calling via jquery is returning a dictionary. If it's impossible to work with the above, what do I need to change about the way I'm returning the data?
Here's an outline of my webmethod:
<WebMethod()> _
Public Function Foo(ByVal Input As String) As Dictionary(Of String, String)
Dim Results As New Dictionary(Of String, String)
'code that does stuff
Results.Add(key,value)
Return Results
End Function
You can use the for..in construct to iterate through arbitrary properties of your object:
for (var key in obj.d) {
console.log("Key: " + key);
console.log("Value: " + obj.d[key]);
}
Is this what you're looking for?
var data;
for (var key in data) {
var value = data[key];
alert(key + ", " + value);
}
{
"d":{
"key1":"value1",
"key2":"value2"
}
}
To access first key write:
let firstKey=Object.keys(d)[0];
To access value of first key write:
let firstValue= d[firstKey];
By using word "b", You are still using key name.
var info = {
"fname": "Bhaumik",
"lname": "Mehta",
"Age": "34",
"favcolor": {"color1":"Gray", "color2":"Black", "color3":"Blue"}
};
Look at the below snippet.
for(key in info) {
var infoJSON = info[key];
console.log(infoJSON);
}
Result would be,
Bhaumik
Mehta
Object {color1: "Gray", color2: "Black", color3: "Blue"}
Don’t want that last line to show up? Try following code:
for(key in info) {
var infoJSON = info[key];
if(typeof infoJSON !== "object"){
console.log(infoJSON);
}
}
This will eliminate Object {color1: “Gray”, color2: “Black”, color3: “Blue”} from showing up in the console.
Now we need to iterate through the variable infoJSON to get array value. Look at the following whole peace of code.
for(key in info) {
var infoJSON = info[key];
if (typeof infoJSON !== "object"){
console.log(infoJSON);
}
}
for(key1 in infoJSON) {
if (infoJSON.hasOwnProperty(key1)) {
if(infoJSON[key1] instanceof Array) {
for(var i=0;i<infoJSON[key1].length;i++) {
console.log(infoJSON[key1][i]);
}
} else {console.log(infoJSON[key1]);}
}
}
And now we got the result as
Bhaumik
Mehta
Gray
Black
Blue
If we use key name or id then it’s very easy to get the values from the JSON object but here we are getting our values without using key name or id.
Use for loop to achieve the same.
var dlist = { country: [ 'ENGLAND' ], name: [ 'CROSBY' ] }
for(var key in dlist){
var keyjson = dlist[key];
console.log(keyjson)
}
How to sort this object lexicographically by its keys:
var obj = {'somekey_B' : 'itsvalue', 'somekey_A' : 'itsvalue');
so that it outputs like this:
for (k in obj) {
alert(k + ' : ' + obj[k]); //first "somekey_A : itsvalue"; then "somekey_B : itsvalue"
}
You can't. The order in which for..in loops through the property names is implementation-specific and cannot be controlled. Your only alternative is to organize the properties yourself in some way, such as building an array of keys and then sorting it, e.g.:
var keys, index;
keys = [];
for (k in obj) {
keys.push(k);
}
keys.sort();
for (index = 0; in dex < keys.length; ++index) {
k = keys[index];
alert(k + ' : ' + obj[k]); //first "somekey_A : itsvalue"; then "somekey_B : itsvalue"
}
You could, of course, put that in a function on the object and use it to iterate through the keys. Alternately, you could keep a sorted array on the object itself, provided you kept it up-to-date when you created new properties.
You need to copy the keys of the object into a sortable data structure, sort it, and use that in your for..in loop to reference the values.
var ob = {
foo: "foo",
bar: "bar",
baz: "baz"
};
var keys = [];
for (key in ob) {
keys.push(key);
}
keys.sort();
keys.forEach(
function (key) {
alert(ob[key]);
}
);
If the object is an arrya (or you made it an array using Prototype, jQuery, etc) you can use the native array.sort() function. You can even use your own callback function for sorting the values.
Say you have a javascript object like this:
var data = { foo: 'bar', baz: 'quux' };
You can access the properties by the property name:
var foo = data.foo;
var baz = data["baz"];
But is it possible to get these values if you don't know the name of the properties? Does the unordered nature of these properties make it impossible to tell them apart?
In my case I'm thinking specifically of a situation where a function needs to accept a series of name-value pairs, but the names of the properties may change.
My thoughts on how to do this so far is to pass the names of the properties to the function along with the data, but this feels like a hack. I would prefer to do this with introspection if possible.
You can loop through keys like this:
for (var key in data) {
console.log(key);
}
This logs "Name" and "Value".
If you have a more complex object type (not just a plain hash-like object, as in the original question), you'll want to only loop through keys that belong to the object itself, as opposed to keys on the object's prototype:
for (var key in data) {
if (data.hasOwnProperty(key)) {
console.log(key);
}
}
As you noted, keys are not guaranteed to be in any particular order. Note how this differs from the following:
for each (var value in data) {
console.log(value);
}
This example loops through values, so it would log Property Name and 0. N.B.: The for each syntax is mostly only supported in Firefox, but not in other browsers.
If your target browsers support ES5, or your site includes es5-shim.js (recommended), you can also use Object.keys:
var data = { Name: 'Property Name', Value: '0' };
console.log(Object.keys(data)); // => ["Name", "Value"]
and loop with Array.prototype.forEach:
Object.keys(data).forEach(function (key) {
console.log(data[key]);
});
// => Logs "Property Name", 0
Old versions of JavaScript (< ES5) require using a for..in loop:
for (var key in data) {
if (data.hasOwnProperty(key)) {
// do something with key
}
}
ES5 introduces Object.keys and Array#forEach which makes this a little easier:
var data = { foo: 'bar', baz: 'quux' };
Object.keys(data); // ['foo', 'baz']
Object.keys(data).map(function(key){ return data[key] }) // ['bar', 'quux']
Object.keys(data).forEach(function (key) {
// do something with data[key]
});
ES2017 introduces Object.values and Object.entries.
Object.values(data) // ['bar', 'quux']
Object.entries(data) // [['foo', 'bar'], ['baz', 'quux']]
for(var property in data) {
alert(property);
}
You often will want to examine the particular properties of an instance of an object,
without all of it's shared prototype methods and properties:
Obj.prototype.toString= function(){
var A= [];
for(var p in this){
if(this.hasOwnProperty(p)){
A[A.length]= p+'='+this[p];
}
}
return A.join(', ');
}
function getDetailedObject(inputObject) {
var detailedObject = {}, properties;
do {
properties = Object.getOwnPropertyNames( inputObject );
for (var o in properties) {
detailedObject[properties[o]] = inputObject[properties[o]];
}
} while ( inputObject = Object.getPrototypeOf( inputObject ) );
return detailedObject;
}
This will get all properties and their values (inherited or own, enumerable or not) in a new object. original object is untouched. Now new object can be traversed using
var obj = { 'b': '4' }; //example object
var detailedObject = getDetailedObject(obj);
for(var o in detailedObject) {
console.log('key: ' + o + ' value: ' + detailedObject[o]);
}
var obj = {
a: [1, 3, 4],
b: 2,
c: ['hi', 'there']
}
for(let r in obj){ //for in loop iterates all properties in an object
console.log(r) ; //print all properties in sequence
console.log(obj[r]);//print all properties values
}
You can use Object.keys(), "which returns an array of a given object's own enumerable property names, in the same order as we get with a normal loop."
You can use any object in place of stats:
var stats = {
a: 3,
b: 6,
d: 7,
erijgolekngo: 35
}
/* this is the answer here */
for (var key in Object.keys(stats)) {
var t = Object.keys(stats)[key];
console.log(t + " value =: " + stats[t]);
}
var attr, object_information='';
for(attr in object){
//Get names and values of propertys with style (name : value)
object_information += attr + ' : ' + object[attr] + '\n';
}
alert(object_information); //Show all Object