I have been banging my head against this all night.
I have a service that is returning data that looks like this:
You will see there are Objects with a GUID, nested under a parent object. I need to loop through all the "GUID" objects and get the attributes (i.e., author, content, etc.).
The GUIDs are dynamic (I don't know what they are ahead of time). The attributes below it are known.
I am having trouble figuring out how to target it. I can't seem to successfully use a for or forEach loop on it.
I need to use native JavaScript (i.e. no jQuery for this one).
Here's a possible solution:
var keys = Object.keys(data);
var results =
keys.map(
function(key){
var datum = data[key];
// do whatever with the data.
return {
"author" : data["author"]
}
}
)
// now results is an array of {"author"} objects.
var x = {
'a-45-2455': {
'author': 'Some Name'
}
};
var keys = Object.keys(x);
keys.forEach(function(key,value){
var author = x[key]['author'];
console.log(author);
});
You can access the data in this way.
You can also create another array from the values and use that.
In order to loop through an object use for...in
Since you have not posted the code of object , here is a snippet with dummy object
var x = {
'a-45-2455': {
'author': 'Some Name'
}
}
for(var keys in x){
alert(x[keys].author)
}
If you are using angular try angular.forEach loop to iterate over all GUID's, else you can use for each in javascript. see below code snippet.
var user ={
'1': {
"name":'abc',
"age":26
},
'2': {
"name":'def',
"age":28
}
};
for(var key in user) {
console.log(user[key].name);
}
Here is another way to iterate through json Object
var obj = {a: 1, b: 2, c: {a: 1, b: 2}};
function walk(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var val = obj[key];
console.log(val);
walk(val);
}
}
}
walk(obj);
var obj = {a: 1, b: 2, c: {a: 1, b: 2}};
function walk(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var val = obj[key];
console.log(val);
walk(val);
}
}
}
walk(obj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I believe that you can iterate through all indexes using the advanced for loop. a.b is the same as a["b"] in javascript.
You can iterate thru the object properties like this:
for(let key in Response){
if(!Response.hasOwnProperty(key))
continue;
//key will be each GUID
let yourObject = Response[key] //Each object in the list of objects
}
You can read about for...in loops here
Hope that helps!
Related
I have a couple of arrays that looks a bit like these:
arr['a'] = 'val1';
arr['b'] = 'val2';
arr['c'] = 'val3';
The index is not an integer, it is a string. I want to remove arr['b'] from the array completely. I have tried:
arr.splice('b', 1);
It does not work, and it might be because the index in not an integer, according to
w3schools this is the problem "index - Required. An integer".
A possible solution could be looping through all arrays and re-creating them with an integer index and then an array holding the custom indexes as values and the equivalent integer index as its index.
This seems like a tad unnecessary and a waste of resources, is there a smarter more effective and simpler solution?
Preferably an arr.splice that will work with a non-integer index.
I have looked through plenty of posts that covers how to remove elements from arrays by index and values, but none covers how to remove elements using a non-integer index.
Example posts that I have found:
0
1
2
Any and all help is greatly appreciated!
//Edit, used following as a solution.
function aObj() {
this.a = "";
this.b = [];
}
var aObjs = [];
aObjs.push(new aObj);
aObjs.push(new aObj);
aObjs.push(new aObj);
aObjs[0].a = "val1";
aObjs.splice(1, 1);
Looks a bit different than what I used in my first example, but this is more accurate towards how I used it. May not be the best way to do it, but it works.
Don't use array for string indexes, use objects like bellow
var arr = {} //create a object
arr['a'] = 'val1'; //asign values
arr['b'] = 'val2';
arr['c'] = 'val3';
console.log(arr) //prints {a: "val1", b: "val2", c: "val3"}
delete arr['a'] //delete a key
console.log(arr) // prints {b: "val2", c: "val3"}
Well it does not work, because you are using an array as a dictionary, which it's not. First of all use object for that. Second use delete to remove a property:
var dict = { 'a': 'val1', 'b': 'val2', 'c': 'val3' };
delete dict.a;
As said before, this is not an Array. If it should be an array, it looks like this
var arr = ['val1', 'val2', 'val3'];
Now you can use Array.splice to remove value 'val2':
arr.splice(1,1);
// or
arr.splice(arr.indexOf('val2'),1);
// or even
arr = arr.filter(function (v){ return v !== 'val2'});
If it should be an object, its declariation looks like:
var obj = {a: 'val1', b: 'val2', c: 'val3'};
And if you want to delete 'val2' whilst not knowing the key for it you can loop:
for (var key in obj) {
if (obj[key] === 'val2';
delete obj[key];
}
// or (mis)use Object.keys
Object.keys(obj)
.filter(function(v){
return this[v] === 'val2' ? !(delete this[v]) : true;
}, obj);
Knowing this, you can create a helper method for Objects and Arrays:
function removeByValue(objOrArr, value) {
if (objOrArr instanceof Array && objOrArr.length) {
var found = objOrArr.indexOf(value);
if (found) { objOrArr.splice(found,1); }
}
if (objOrArr instanceof Object) {
var keys = Object.keys(objOrArr);
if (keys.length) {
keys.filter(function(v){
return this[v] === value ? !(delete this[v]) : true;
}, objOrArr);
}
}
return objOrArr;
}
// usage (using previous arr/obj)
removeByValue(arr, 'val2'); // arr now ['val1','val3']
removeByValue(obj, 'val2'); // obj now {a:'val1', c: 'val3'}
Example
I have an array like this:
var myArray = new Array();
myArray['foo'] = {
Obj: {
key: value
}
};
myArray['bar'] = {
Obj: {
key: value
}
};
When I do console.log(myArray) I just get empty [ ]. And when I try to iterate the array using jQuery's each the function doesn't run.
How can I get the 'foo' and 'bar' parts of the array?
Example code:
console.log(myArray); // [ ]
jQuery.each(myArray, function(key, obj) {
console.log(key); // should be 'foo' following by 'bar'
});
In addition, why does this work:
jQuery.each(myArray[foo], function(obj, values) {
// Why does this work if there are no associative arrays in JS?
});
you can get keys by:
Object.keys(variable name);
it returns array of keys.
You need to define it as an object if you want to access it like that:
var myObj= {};
myObj.foo = ...;
myObj.bar = ...;
Now you can access the properties like myObj["bar"] or myObj.bar
Note:
To loop through all the properties it's wise to add an additional check. This is to prevent you from looping through inherited properties.
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
// Do stuff.
}
}
Array is a collection where each element has an index.
To add element to array you can use push method
myArray.push('someValue');
or set element by index (if length of array < index):
myArray.push('someValue1');
myArray.push('someValue1');
myArray[0] = 'new someValue1';
Note that array is an instance of Object class, so you can add/edit any property of this object:
myArray.foo = '1';
myArray['bar'] = '2';
In this case you will not add new element to array, you defining new properties of object.
And you don't need to create object as Array if you don't wont to use indexes.
To create new object use this code:
var myObj = {};
To get all properties of object see
How to get all properties values of a Javascript Object (without knowing the keys)?
var myArray = {};
myArray['foo'] = { 'key': 'value' }
myArray['bar'] ={ 'key': 'value' }
console.log(myArray)
jQuery.each(myArray['foo'], function(obj, values) {
console.log(obj, values)
});
Demo
With your Array of Objects you could use this function:
var getKeys = function(obj) {
if (!(typeof obj == "object")) return [];
var keys = [];
for (var key in obj) if (obj != null && hasOwnProperty.call(obj, key)) keys.push(key);
return keys;
};
getKeys(myArray) would give you an array of your Keys.
This is basically a cleared up version of underscores _.keys(myArray) function. You should consider using underscore.
// $.each() function can be used to iterate over any collection, whether it is an object or an array.
var myArray = {};
myArray['alfa'] = 0;
myArray['beta'] = 1;
$.each(myArray, function(key, value) {
alert(key);
});
Note: checkout http://api.jquery.com/jQuery.each/ for more information.
I need to populate a json file, now I have something like this:
{"element":{"id":10,"quantity":1}}
And I need to add another "element". My first step is putting that json in a Object type using cart = JSON.parse, now I need to add the new element.
I supposed I must use cart.push to add another element, I tried this:
var element = {};
element.push({ id: id, quantity: quantity });
cart.push(element);
But I got error "Object has no method push" when I try to do element.push, and I think I'm doing something VERY wrong because I'm not telling the "element" anywhere.
How can I do that?
Edit: sorry to all I had a LOT of confusion in my head.
I thought I can get only object type when taking data from JSON.parse, but I get what I put in the JSON in the first place.
Putting array instead of object solved my problem, I used lots of suggestions got here too, thank you all!
Your element is not an array, however your cart needs to be an array in order to support many element objects. Code example:
var element = {}, cart = [];
element.id = id;
element.quantity = quantity;
cart.push(element);
If you want cart to be an array of objects in the form { element: { id: 10, quantity: 1} } then perform:
var element = {}, cart = [];
element.id = id;
element.quantity = quantity;
cart.push({element: element});
JSON.stringify() was mentioned as a concern in the comment:
>> JSON.stringify([{a: 1}, {a: 2}])
"[{"a":1},{"a":2}]"
The line of code below defines element as a plain object.
let element = {}
This type of JavaScript object with {} around it has no push() method. To add new items to an object like this, use this syntax:
element[yourKey] = yourValue
To put it all together, see the example below:
let element = {} // make an empty object
/* --- Add Things To The Object --- */
element['active'] = true // 'active' is the key, and 'true' is the value
console.log(element) // Expected result -> {type: true}
element['state'] = 'slow' // 'state' is the key and 'slow' is the value
console.log(element) // Expected result -> {type: true, state: 'slow'}
On the other hand, if you defined the object as an array (i.e. using [] instead of {}), then you can add new elements using the push() method.
To append to an object use Object.assign
var ElementList ={}
function addElement (ElementList, element) {
let newList = Object.assign(ElementList, element)
return newList
}
console.log(ElementList)
Output:
{"element":{"id":10,"quantity":1},"element":{"id":11,"quantity":2}}
If the cart has to be stored as an object and not array (Although I would recommend storing as an []) you can always change the structure to use the ID as the key:
var element = { quantity: quantity };
cart[id] = element;
This allows you to add multiple items to the cart like so:
cart["1"] = { quantity: 5};
cart["2"] = { quantity: 10};
// Cart is now:
// { "1": { quantity: 5 }, "2": { quantity: 10 } }
Adding new key/pair elements into the original object:
const obj = { a:1, b:2 }
const add = { c:3, d:4, e: ['x','y','z'] }
Object.entries(add).forEach(([key,value]) => { obj[key] = value })
obj new value:
{a: 1, b: 2, c: 3, d: 4, e: ['x', 'y', 'z'] }
I was reading something related to this try if it is useful.
1.Define a push function inside a object.
let obj={push:function push(element){ [].push.call(this,element)}};
Now you can push elements like an array
obj.push(1)
obj.push({a:1})
obj.push([1,2,3])
This will produce this object
obj={
0: 1
1: {a: 1}
2: (3) [1, 2, 3]
length: 3
}
Notice the elements are added with indexes and also see that there is a new length property added to the object.This will be useful to find the length of the object too.This works because of the generic nature of push() function
you should write var element = [];
in javascript {} is an empty object and [] is an empty array.
cart.push({"element":{ id: id, quantity: quantity }});
function addValueInObject(object, key, value) {
var res = {};
var textObject = JSON.stringify(object);
if (textObject === '{}') {
res = JSON.parse('{"' + key + '":"' + value + '"}');
} else {
res = JSON.parse('{' + textObject.substring(1, textObject.length - 1) + ',"' + key + '":"' + value + '"}');
}
return res;
}
this code is worked.
Try this:
var data = [{field:"Data",type:"date"}, {field:"Numero",type:"number"}];
var columns = {};
var index = 0;
$.each(data, function() {
columns[index] = {
field : this.field,
type : this.type
};
index++;
});
console.log(columns);
If anyone comes looking to create a similar JSON, just without using cart as an array, here goes:
I have an array of objects myArr as:
var myArr = [{resourceType:"myRT",
id: 1,
value:"ha"},
{resourceType:"myRT",
id: 2,
value:"he"},
{resourceType:"myRT",
id: 3,
value:"Li"}];
and I will attempt to create a JSON with the following structure:
{
"1":{"resourceType":"myRT","id":"1","value":"ha"},
"2":{"resourceType":"myRT","id":"2","value":"he"},
"3":{"resourceType":"myRT","id":"3","value":"Li"}
}
you can simply do-
var cart = {};
myArr.map(function(myObj){
cart[myObj.id]= myObj;
});
function addValueInObject(value, object, key) {
var addMoreOptions = eval('{"' + key + '":' + value + '}');
if(addMoreOptions != null) {
var textObject = JSON.stringify(object);
textObject = textObject.substring(1,textObject.length-1);
var AddElement = JSON.stringify(addMoreOptions);
object = eval('{' + textObject +','+ AddElement.substring(1,AddElement.length-1) + '}');
}
return object;
}
addValueInObject('sdfasfas', yourObject, 'keyname');
OR:
var obj = {'key':'value'};
obj.key2 = 'value2';
For anyone still looking for a solution, I think that the objects should have been stored in an array like...
var element = {}, cart = [];
element.id = id;
element.quantity = quantity;
cart.push(element);
Then when you want to use an element as an object you can do this...
var element = cart.find(function (el) { return el.id === "id_that_we_want";});
Put a variable at "id_that_we_want" and give it the id of the element that we want from our array. An "elemnt" object is returned. Of course we dont have to us id to find the object. We could use any other property to do the find.
My proposition is to use different data structure that proposed already in other answers - it allows you to make push on card.elements and allow to expand card properties:
let card = {
elements: [
{"id":10,"quantity":1}
],
//other card fields like 'owner' or something...
}
card.elements.push({"id":22,"quantity":3})
console.log(card);
push is an method of arrays , so for object you can get the index of last element ,and you can probably do the same job as push for object as below
var lastIndex = Object.keys(element)[Object.keys(element).length-1];
then add object to the new index of element
element[parseInt(lastIndex) +1] = { id: id, quantity: quantity };
if you not design to do loop with in JS e.g. pass to PHP to do loop for you
let decision = {}
decision[code+'#'+row] = event.target.value
this concept may help a bit
This is an old question, anyway today the best practice is by using Object.defineProperty
const object1 = {};
Object.defineProperty(object1, 'property1', {
value: 42,
writable: false
});
object1.property1 = 77;
// throws an error in strict mode
console.log(object1.property1);
// expected output: 42
In case anyone else needs this, I finally found a good way to add objects or arrays of objects:
var myobj = {}
// These two options only work for single-valued keys, not arrays or objects
myobj["a"] = 1
myobj.b = 2
// This one works for everyting:
Object.assign(myobj, {"key": "value"}); // single-value
// Add object
Object.assign(myobj, {"subobj":
{
"c": 3
}
});
// Add array of objects
Object.assign(myobj, {"subarr":
[
{
"d": 4,
},
{
"e": 5
}
]
});
var newObject = {element:{"id":10,"quantity":1}};
console.log(newObject);
Consider:
var object = {
foo: {},
bar: {},
baz: {}
}
How would I do this:
var first = object[0];
console.log(first);
Obviously, that doesn’t work because the first index is named foo,
not 0.
console.log(object['foo']);
works, but I don’t know it’s named foo. It could be named anything. I just want the first.
Just for fun this works in JS 1.8.5
var obj = {a: 1, b: 2, c: 3};
Object.keys(obj)[0]; // "a"
This matches the same order that you would see doing
for (o in obj) { ... }
If you want something concise try:
for (first in obj) break;
alert(first);
wrapped as a function:
function first(obj) {
for (var a in obj) return a;
}
they're not really ordered, but you can do:
var first;
for (var i in obj) {
if (obj.hasOwnProperty(i) && typeof(i) !== 'function') {
first = obj[i];
break;
}
}
the .hasOwnProperty() is important to ignore prototyped objects.
This will not give you the first one as javascript objects are unordered, however this is fine in some cases.
myObject[Object.keys(myObject)[0]]
If the order of the objects is significant, you should revise your JSON schema to store the objects in an array:
[
{"name":"foo", ...},
{"name":"bar", ...},
{"name":"baz", ...}
]
or maybe:
[
["foo", {}],
["bar", {}],
["baz", {}]
]
As Ben Alpert points out, properties of Javascript objects are unordered, and your code is broken if you expect them to enumerate in the same order that they are specified in the object literal—there is no "first" property.
for first key of object you can use
console.log(Object.keys(object)[0]);//print key's name
for value
console.log(object[Object.keys(object)[0]]);//print key's value
There is no way to get the first element, seeing as "hashes" (objects) in JavaScript have unordered properties. Your best bet is to store the keys in an array:
var keys = ["foo", "bar", "baz"];
Then use that to get the proper value:
object[keys[0]]
ES6
const [first] = Object.keys(obj)
Using underscore you can use _.pairs to get the first object entry as a key value pair as follows:
_.pairs(obj)[0]
Then the key would be available with a further [0] subscript, the value with [1]
I had the same problem yesterday. I solved it like this:
var obj = {
foo:{},
bar:{},
baz:{}
},
first = null,
key = null;
for (var key in obj) {
first = obj[key];
if(typeof(first) !== 'function') {
break;
}
}
// first is the first enumerated property, and key it's corresponding key.
Not the most elegant solution, and I am pretty sure that it may yield different results in different browsers (i.e. the specs says that enumeration is not required to enumerate the properties in the same order as they were defined). However, I only had a single property in my object so that was a non-issue. I just needed the first key.
You could do something like this:
var object = {
foo:{a:'first'},
bar:{},
baz:{}
}
function getAttributeByIndex(obj, index){
var i = 0;
for (var attr in obj){
if (index === i){
return obj[attr];
}
i++;
}
return null;
}
var first = getAttributeByIndex(object, 0); // returns the value of the
// first (0 index) attribute
// of the object ( {a:'first'} )
To get the first key of your object
const myObject = {
'foo1': { name: 'myNam1' },
'foo2': { name: 'myNam2' }
}
const result = Object.keys(myObject)[0];
// result will return 'foo1'
Based on CMS answer. I don't get the value directly, instead I take the key at its index and use this to get the value:
Object.keyAt = function(obj, index) {
var i = 0;
for (var key in obj) {
if ((index || 0) === i++) return key;
}
};
var obj = {
foo: '1st',
bar: '2nd',
baz: '3rd'
};
var key = Object.keyAt(obj, 1);
var val = obj[key];
console.log(key); // => 'bar'
console.log(val); // => '2nd'
My solution:
Object.prototype.__index = function(index)
{
var i = -1;
for (var key in this)
{
if (this.hasOwnProperty(key) && typeof(this[key])!=='function')
++i;
if (i >= index)
return this[key];
}
return null;
}
aObj = {'jack':3, 'peter':4, '5':'col', 'kk':function(){alert('hell');}, 'till':'ding'};
alert(aObj.__index(4));
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