How can I get member names from an object? [duplicate] - javascript

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Getting JavaScript object key list
How to iterate json data in jquery
I have a json like this one:
var myJSONObject = {
"flowers": [
{"id":"1","name":"Red Flower","url":"flower_1.png"},
{"id":"2","name":"Purple Flower","url":"flower_2.png"},
{"id":"3","name":"Yellow Flower","url":"flower_3.png"},
{"id":"4","name":"Violet Flower","url":"flower_4.png"},
{"id":"5","name":"Purple Flower","url":"flower_5.png"}
],
"bouquet": [
{"first":[1,2,3,4,5,6]},
{"second":[1,2,3,4,5,6]},
{"third":[1,2,3,4,5,6]}
]
};
Now my questin is how can I pull only the names of members of "bouquet"...into array.
Something that will look like that : ["first","second","third"]?

In recent Firefox browsers, the following can be used (so-called Array-comprehensions):
var list = [Object.keys(i)[0] for each (i in myJSONObject.bouquet)];
If Object.keys is supported, use:
var list = []; // Create list
for (var i=0; i<myJSONObject.bouquet.length; i++) {
var keys = Object.keys(myJSONObject.bouquet[i]); //List keys
list.push(keys[0]); // Store first named key
}
In other browsers, you can use:
var list = []; // Create list
for (var i=0; i<myJSONObject.bouquet.length; i++) {
var key = myJSONObject.bouquet[i];
for (var j in key) { // Get the first named key
list.push(j); // Store named key
break; // <--- First named key, so break loop
}
}

for(var i=0; i< myJSONObject["bouquet"].length; i++)
{
var o = myJSONObject["bouquet"][i];
document.write(Object.keys(o) + "<br>");
}
output: first second third
JSFiddle for confirmation

if you are in an environment that supports modern ECMA additions, you can use Object.keys (docs here) or you can polyfill your own if you need to, something like this:
function getKeys(obj) {
var ret = [], prop;
for (prop in obj) {
if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) {
ret.push( prop );
}
}
return ret;
};
Usage:
var keys = getKeys({ foo: "a", bar: "b" }); // -> ['foo', 'bar']
hope that helps! cheers.

Related

Javascript number of object by different property values in array

Best way to count the number of objects in a array with different object property p values.
function([{"p":"a"},{"p":"b"},{"p":"a"}]){
// some code
}
// in this case return 2
You can use Array.prototype.filter() to keep values that you want. In this case, you must create a variable temp for storing duplicate values and also within the filter function returns true if it does not exist in case. So you have a new array of unique values.
var arr = [{"p":"a"},{"p":"b"},{"p":"a"}], temp = [];
var arrUniques = arr.filter(function(obj){
return temp.indexOf(obj.p) === -1 ? !!temp.push(obj.p) : false
});
alert(arrUniques.length)
With a Map:
var props = new Map();
for (var i = 0; i < array.length; i++) {
var prop = array[i].p,
count = props.get(prop) || 0;
props.set(prop, count + 1);
}
var size = props.size;
If your properties can be safely casted to strings, you can use a common object:
var props = {};
...
var size = Object.keys(props).length;
Otherwise, Map is your answer.
function getUniquePropertyCount(a, p) {
return a.reduce(function (res, el) {
!~res.indexOf(el[p]) && res.push(el[p]);
return res;
}, []).length;
}
document.write(getUniquePropertyCount([{ "p": "a" }, { "p": "b" }, { "p": "a" }], 'p'));
I suppose this is one of those questions where if you ask four programmers, you'll get five answers.
The other answers so far show some interesting approaches. I would watch out for browser compatibility; for example Map() is only available in the newest browsers, not in IE 10 or prior.
So here's one more solution. It's a bit more code, but it's pretty easy to understand, and it works in every browser:
function countUniqueProperties( key, array ) {
var count = 0, values = {};
for( var i = 0; i < array.length; ++i ) {
var value = array[i][key];
if( ! Object.prototype.hasOwnProperty.call( values, value) ) {
++count;
values[value] = true;
}
}
return count;
}
countUniqueProperties( 'p', [ {p:'a'}, {p:'b'}, {p:'a'} ] );
The one complicated part here is the Object.prototype.hasOwnProperty.call(values,value). You could just use values.hasOwnProperty(value), but that would fail if one of your property values was the string "hasOwnProperty":
countUniqueProperties( 'p', [ {p:'a'}, {p:'hasOwnProperty'}, {p:'a'} ] );
Using the longer form avoids this issue.
lodash is nice for things like this.
Use
_.uniq([{"p":"a"},{"p":"b"},{"p":"a"}]).length
and it'll return 2.

Javascript: how to dynamically create nested objects INCLUDING ARRAYS using object names given by an array

Very similar to this question:
Javascript: how to dynamically create nested objects using object names given by an array
Instead of calling
assign(obj, keyPath, value)
example of usage of the previously answer:
var accountinfo = {}
assign(accountinfo, ["name", "addressinfo", "zipcode"], "90210");
That will output:
accountinfo = {name: "", addressinfo: {zipcode:"90210"}};
Now, I'd like to support arrays... in the above example, I'd like to support multiple addressinfo per account. I'd like to say:
assign(accountinfo, ["name", "addressinfo[1]", "zipcode"], "90210");
The result would be:
accountinfo = {name: "", addressinfo: [{},{zipcode:"90210"}]}
var regex = /\[([0-9]+)\]/ will show me the # inside the brackets, but I'm not sure how I'd have to iterate through each element in the array to make sure it exists (and create it if it doesn't).. and the difficult part, support this for each array element submitted as part of the function (I'd like to say :
assign(accountinfo, ["family", "name[3]", "addressinfo[1]", "zipcode"], "90210");
Edit:
Figured it out.
function assign(obj, keyPath, value) {
keyPath = keyPath.split(‘.’);
lastKeyIndex = keyPath.length - 1;
var re = /^(.+?)\[*(\d+)*\]*$/;
for (var i = 0; i < lastKeyIndex; i++) {
key = keyPath[i];
var ind;
var middle = re.exec(key);
key = middle[1];
ind = middle[2];
if (ind) {
if (!(obj[key]))
obj[key] = [];
if (!(obj[key][ind]))
obj[key][ind] = {};
}
if (!(key in obj))
obj[key] = {};
if (ind)
obj = obj[key][ind];
else
obj = obj[key];
}
obj[keyPath[lastKeyIndex]] = value;
}

Returning only certain properties from an array of objects in Javascript [duplicate]

This question already has answers here:
From an array of objects, extract value of a property as array
(24 answers)
Closed 8 years ago.
If I have an object such that
var object = function(key,text)
{
this.key = key;
this.text = text;
}
And create an array of these objects
var objArray = [];
objArray[0] = new object('key1','blank');
objArray[1] = new object('key2','exampletext');
objArray[2] = new object('key3','moretext');
is there a way that I can retrieve only one of the properties of all of the objects in the array? For example:
var keyArray = objArray["key"];
The above example doesn't return set keyArray to anything, but I was hoping it would be set to something like this:
keyArray = [
'key1',
'key2',
'key3']
Does anyone know of a way to do this without iterating through the objArray and manually copying each key property to the key array?
This is easily done with the Array.prototype.map() function:
var keyArray = objArray.map(function(item) { return item["key"]; });
If you are going to do this often, you could write a function that abstracts away the map:
function pluck(array, key) {
return array.map(function(item) { return item[key]; });
}
In fact, the Underscore library has a built-in function called pluck that does exactly that.
var object = function(key,text) {
this.key = key;
this.text = text;
}
var objArray = [];
objArray[0] = new object('key1','blank');
objArray[1] = new object('key2','exampletext');
objArray[2] = new object('key3','moretext');
var keys = objArray.map(function(o,i) {
return o.key;
});
console.log(keys); // ["key1", "key2", "key3"]
JS Bin Example
http://jsbin.com/vamey/1/edit
Note that older browsers may not support map but you can easily do this with a for loop:
var keys = [];
for (var i = 0; i < objArray.length; i++) {
keys.push(objArray[i].key);
}
JS Bin Example
http://jsbin.com/redis/1/edit
You would want to do something like this:
objArray.map(function (obj) { return obj.key; });
Here is a JSFiddle to demo: http://jsfiddle.net/Q7Cb3/
If you need older browser support, you can use your own method:
JSFiddle demo: http://jsfiddle.net/Q7Cb3/1/
function map (arr, func) {
var i = arr.length;
arr = arr.slice();
while (i--) arr[i] = func(arr[i]);
return arr;
}
Well something has to iterate through the elements of the array. You can use .map() to make it look nice:
var keys = objArray.map(function(o) { return o.key; });
You could make a function to generate a function to retrieve a particular key:
function plucker(prop) {
return function(o) {
return o[prop];
};
}
Then:
var keys = objArray.map(plucker("key"));
Really "objArray" is an array that have 3 objects inside, if you want list of keys, you can try this:
var keys = [];
for(a in objArray) {
keys.push(objArray[a].key);
}
You have in var keys, the three keys.
Hope that helps! :)

Push an object into the object list object

The simplest question ever, and I did not find right answer yet.
Got object list: object_list = {}
Got object: object_x = {...}
How do I add object_x to object_list[objects_x]?
I tried: object_list[objects_x][object_list[objects_x].length] = object_x, but object_list[objects_x].length is undefined.
push() does not work either.
Do I really need to define external counter for that?
PLEASE NOT THAT I MEAN LIST OF LISTS OF OBJECTS. NOTE THE DIFFERENCE BETWEEN objects_x and object_x.
There is no simple solution like in PHP where you simply $array['something'][] = $somedata ?
object_list['object_x'] = object_x;
// or
object_list.object_x = object_x;
console.log(object_list.object_x === object_list['object_x'])
How to work with objects - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
When you create a variable like var stuff = {}, you're creating an empty object literal, it has no attributes (properties or methods) other than what it inherits from Object. If you want to keep objects stored in various lists in this object you need to first create those lists.
var stuff = { shelves: [], selectors: [], images: [], additional: [] };
Now you can add whatever you want to those lists as much as you want.
var image = { src: '/path/to/image.jpg' };
stuff.images.push(image);
You can add more lists to stuff whenever like by just setting the new property on stuff.
stuff.some_other_list = []
Hope it helps.
Your base assumption is wrong.
This:
var object_list = {}
Is not a list. It's not an array and you can't reference its items by index, thus it also does not have .length property.
What you are after is a plain array:
var object_list = [];
Now you can push items into it:
object_list.push(object_x);
Edit: based on your comments and edits, I think what you're really after are couple of helper functions:
function AddToList(list, item) {
var counter = 0;
for (var key in list)
counter++;
var key = "item_index_" + counter;
list[key] = item;
}
function GetItemByIndex(list, index) {
var counter = 0;
var existingKey = "";
for (var key in list) {
if (counter == index) {
existingKey = key;
break;
}
counter++;
}
return (existingKey.toString().length > 0) ? list[existingKey] : null;
}
Having those, you can have such a code now:
var mainList = {};
var newItem = { "foo": "bar" };
AddToList(mainList, newItem);
var dummy = GetItemByIndex(mainList, 0)["foo"]; //will contain "bar"
Live test case.
If you are interested use object, not array, you can use like this:
var object_list = {};
var object_x = {'prop1':'val1'};
// add object
object_list.myobj = object_x;
// for access, same scheme.
object_list.myobj.prop1 = 'valX';
// for loop thru
for (var key in object_list) {
var obj = object_list[key];
obj.prop1 = 'valY';
}

Sort complex JSON based on particular key

I have a JSON object with the following format:
{
items:{
nestedObj:{
position:3
},
nestedObj2:{
position:1
},
nestedObj3:{
position:2,
items:{
dblNestedObj:{
position:2
},
dblNestedObj2:{
position:3
},
dblNestedObj3:{
position:1
}
}
}
}
}
I am attempting to sort each level of nested object by their position attribute. I can recursively iterate the object, but I don't know where to start for sorting it...
Unfortunately it's not quite so easy to use the sort method as it would if you had an array. So let's build an array:
var tmp = [], x;
for( x in obj.items) { // assuming your main object is called obj
tmp.push([x,obj.items[x].position]);
// here we add a pair to the array, holding the key and the value
}
// now we can use sort()
tmp.sort(function(a,b) {return a[1]-b[1];}); // sort by the value
// and now apply the sort order to the object
var neworder = {}, l = tmp.length, i;
for( i=0; i<l; i++) neworder[tmp[i][0]] = obj.items[tmp[i][0]];
obj.items = neworder;

Categories

Resources