I'm getting JSON name/value pairs that looks like this:
{
"Name":"parentid",
"Value":"blah"
},
{
"Name":"siteid",
"Value":"blah"
},
{
"Name":"sitename",
"Value":"blah"
}
But I would like to access the "name" value as the KEY, and the "value" value as the VALUE. Is there an elegant way to turn that piece of JSON into something like this?
{'parentid', 'blah'},
{'sitename', 'blah'}
Try this:
var items = [
{
"Name":"parentid",
"Value":"blah"
},
{
"Name":"siteid",
"Value":"blah"
},
{
"Name":"sitename",
"Value":"blah"
}
];
var results = new Object();
for (var i = 0; i < items.length; i++)
{
results[items[i].Name] = items[i].Value;
}
This will result in something like:
var results = { parentid: "Blah", siteid: "Blah", sitename: "Blah" };
One way to do it.
var json = [
{
"Name":"parentid",
"Value":"blah"
},
{
"Name":"siteid",
"Value":"blah"
},
{
"Name":"sitename",
"Value":"blah"
}
];
for ( var i = 0, l = json.length, obj; i < l; i++ )
{
obj = json[i];
json[i] = new Object();
json[i][obj.Name] = obj.Value;
}
// console.log() requires Firebug
console.log( json );
function objectflatten (array) {
var out = {}, i;
for(i = 0; i < array.length; i++) {
out[array[i].name] = array[i].value;
}
return out;
}
This is a function that will take an object in the form you presented, and output it as a "normal" object with the name values as keys, and the value values as values.
I'd recommend using the for( ... in ... ) method for this task. It'll grab the key names like you need.
var jsonObj = eval( '([{ "Name":"parentid", "Value":"blah" }])' );
for( var i = 0, assoc = {}, key; i < jsonObj.length; ++i )
{
for( key in jsonObj[ i ] ) // <-- this right here
{
assoc[ key ] = jsonObj[ i ][ key ];
}
}
and you end up with (from Firebug)
Object Name=parentid Value=blah
that can be accessed by object.key or object[ 'key' ] (in our case assoc.Name or assoc[ 'Value' ])
here's a link from Douglas Crockford from Yahoo! about using it as well - http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
I'm assuming you are using PHP, and the PHP echoes you assosiatice aray like this:
echo json_encode($result);
In your javascript, you could do this:
// Soemthing retrieves php result and puts it in `var result`.
data = eval("(" + result+ ")");
alert(data.parentid);
I'm not sure if this is what you want, but it's a solution.
Related
I have an array of objects like this:
[
{ "key": "fruit", "value": "apple" },
{ "key": "color", "value": "red" },
{ "key": "location", "value": "garden" }
]
I need to convert it to the following format:
[
{ "fruit": "apple" },
{ "color": "red" },
{ "location": "garden" }
]
How can this be done using JavaScript?
You can use .map
var data = [
{"key":"fruit","value":"apple"},
{"key":"color","value":"red"},
{"key":"location","value":"garden"}
];
var result = data.map(function (e) {
var element = {};
element[e.key] = e.value;
return element;
});
console.log(result);
also if you use ES2015 you can do it like this
var result = data.map((e) => {
return {[e.key]: e.value};
});
Example
Using an arrow function, with the data called arr
arr.map(e => {
var o = {};
o[e.key] = e.value;
return o;
});
This generates a new Array and does not modify the original
It can be simplified down to one line as
arr.map(e => ({[e.key]: e.value}));
If you can't assume arrow function support yet, you would write this longhand
arr.map(function (e) {
var o = {};
o[e.key] = e.value;
return o;
});
Using map (as suggested in other answers) or the following will do what you want...
var data = [{"key":"fruit","value":"apple"},{"key":"color","value":"red"},{"key":"location","value":"garden"}];
var obj = {};
for(var i = 0; i < data.length; i++) {
obj[data[i]["key"]] = data[i]["value"];
}
In Javascript, obj.property and obj['property'] return same things.
obj['property'] is more flexible because the key 'property' could be a string with some space :
obj['pro per ty'] // work
obj.pro per ty // not work
or
var a = 'property';
obj.a == obj.property // => false
obj[a] == obj.property // => true
So you could try that.
var data = [{"key":"fruit","value":"apple"},{"key":"color","value":"red"},{"key":"location","value":"garden"}]
var new_data = [];
var data_length = data.length; // just a little optimisation for-loop
for (var i = 0; i < data_length; i++) {
var item = data[i]; // to have a vision close of foreach-loop (foreach item of collection)
new_data[i] = {};
new_data[i][item.key] = item.value;
}
console.log(new_data);
// [{"fruit":"apple"},{"color":"red"},{"location":"garden"}]
What you currently have is an array of object, each having two attributes, key and value. If you are not aware of map, you can always run a forEach loop on this array and rearrange the data. Try something like below:
function() {
var newArray = [];
oldArray.forEach(function(x){
var obj= {};
obj[x.key] = x.value;
newArray.push(obj);
});
console.log(newArray);
}
here oldArray is your original data
Is there a way to get the value of
{
"first": "first-string",
"second-array": [
{
"first-Obj": 2
}
]
}
is there a way to get or update the values by using a path like string
ex: to change the first-obj's value to 1000
changeTheValueAt('second-array/0/firstObj', 1000)
is there any function like above changeTheValueAt or a method.
Use the following function for that -
function changeTheValueAt(obj, path, value) {
var parts = path.split("/"),
final = obj[parts[0]],
i;
for (i = 1; i < parts.length; i++) {
if (i + 1 < parts.length) {
final = final[parts[i]];
}
else {
final[parts[i]] = value;
}
}
}
and then call it like this -
var ob = {
"first": "first-string",
"second-array": [
{
"first-Obj": 2
}
]
};
changeTheValueAt(ob, "second-array/0/first-Obj", 1000)
alert(ob["second-array"][0]["first-Obj"]);
JSFiddle Demo.
Because second-array is an array, you can't access it by name. You can access it by index or you can iterate over and find a value and change it when found.
var yourObj = {
"first": "first-string",
"second-array": [
{
"first-Obj": 2
}
]
};
yourObject.second-array[0].first-Obj = 1000;
You could do something like:
var changeFirstObj = function(node1, node2, new val){
yourObj[node1].forEach(o, i){
for(var prop in o){
if(prop == node2){
o[node2]=newVal;
}
};
changeFirstObj('second-array', 'first-Obj', 1000);
But that's not really very flexible.
I would like to find index in array. Positions in array are objects, and I want to filter on their properties. I know which keys I want to filter and their values. Problem is to get index of array which meets the criteria.
For now I made code to filter data and gives me back object data, but not index of array.
var data = [
{
"text":"one","siteid":"1","chid":"default","userid":"8","time":1374156747
},
{
"text":"two","siteid":"1","chid":"default","userid":"7","time":1374156735
}
];
var filterparams = {userid:'7', chid: 'default'};
function getIndexOfArray(thelist, props){
var pnames = _.keys(props)
return _.find(thelist, function(obj){
return _.all(pnames, function(pname){return obj[pname] == props[pname]})
})};
var check = getIndexOfArray(data, filterparams ); // Want to get '2', not key => val
Using Lo-Dash in place of underscore you can do it pretty easily with _.findIndex().
var index = _.findIndex(array, { userid: '7', chid: 'default' })
here is thefiddle hope it helps you
for(var intIndex=0;intIndex < data.length; intIndex++){
eachobj = data[intIndex];
var flag = true;
for (var k in filterparams) {
if (eachobj.hasOwnProperty(k)) {
if(eachobj[k].toString() != filterparams[k].toString()){
flag = false;
}
}
}
if(flag){
alert(intIndex);
}
}
I'm not sure, but I think that this is what you need:
var data = [{
"text":"one","siteid":"1","chid":"default","userid":"8","time":1374156747
}, {
"text":"two","siteid":"1","chid":"default","userid":"7","time":1374156735
}];
var filterparams = {userid:'7', chid: 'default'};
var index = data.indexOf( _.findWhere( data, filterparams ) );
I don't think you need underscore for that just regular ole js - hope this is what you are looking for
var data = [
{
"text":"one","siteid":"1","chid":"default","userid":"8","time":1374156747
},
{
"text":"two","siteid":"1","chid":"default","userid":"7","time":1374156735
}
];
var userid = "userid"
var filterparams = {userid:'7', chid: 'default'};
var index;
for (i=0; i < data.length; i++) {
for (prop in data[i]) {
if ((prop === userid) && (data[i]['userid'] === filterparams.userid)) {
index = i
}
}
}
alert(index);
How can I convert something like initialArray array of JSON objects into finalObject map?
var initialArray = [
{ id:'id1', name:'name1' },
{ id:'id2', name:'name2' },
{ id:'id3', name:'name3' },
{ id:'id4', name:'name4' }
];
var finalObject = {
'id1':'name1',
'id2':'name2',
'id3':'name3',
'id4':'name4'
}
Things to consider:
IDs are strings.
I tried for in loop - couldn't make it to work - http://jsfiddle.net/5af9R/23/
Any ideas?
You need to operate on the objects in your array, not strings containing their indexes in the array.
You should also use a regular for loop to iterate over an array.
Your JSFiddle, fixed:
var x = [ {id:'1', img:'img1'}, {id:'2', img:'img2'}, {id:'3', img:'img3'} ];
var resp = {};
for( var i = 0 ; i < x.length ; i++ ){
var obj = x[i];
resp[obj.id] = obj.img;
}
document.write( JSON.stringify(resp, undefined, 2) );
DEMO
You can loop over the array, and for each object, add a new property to finalObject whose property name is the id, and whose value is the name.
var finalObject = {};
for (var i = 0, max = initialArray.length; i < max; i++)
finalObject[initialArray[i].id] = initialArray[i].name;
resp[key.id] = key.img;
You correctly call it key. But you need a value;
resp[x[key].id] = x[key].img;
var finalObject = initialArray.reduce(function(ret, obj){
ret[obj.id] = obj.name;
return ret;
}, {});
This solution is specific to the property names for the specific question, but Array.prototype.reduce is a function I use all the time for any sort of array iteration that requires a non-array result.
You're not using For In correctly jsFiddle
var x = [ {id:'1', img:'img1'}, {id:'2', img:'img2'}, {id:'3', img:'img3'} ];
var resp = {};
for( var key in x ){
resp['id' + x[key].id] = x[key].img;
}
document.write( JSON.stringify(resp, undefined, 2) );
for (var i=0; i<x.length; i++) {
var id = 'id' + x[i].id;
var img = x[i].img;
resp[id] = img;
}
if i have understood correctly you can do something like
var x =' [ {"id":"1", "img":"img1"}, {"id":"2", "img":"img2"}, {"id":"3", "img":"img3"}]';
var resp = {};
var json = $.parseJSON(x);
$(json).each(function(i,v){
resp[v.id]=v.img;
});
console.log( resp);
DEMO
you talked about json but in the fiddle you provided there was no json even jquery was not added as a resource so i made some assumptions
Today I was on the same question and I didn't find an answer here, except the answer of #adam-rackis.
The way I found is :
var initialArray = [
{ id:'id1', name:'name1' },
{ id:'id2', name:'name2' },
{ id:'id3', name:'name3' },
{ id:'id4', name:'name4' }
],
finalObject = {};
$.each(initialArray, function(k,v) {
finalObject[v.name] = v.value;
});
I've got a JSON response that looks like this:
{
"COLUMNS":["SETTING_NAME","SETTING_VALUE","COLOR"],
"DATA": [
["setting_1",100.0,"yellow"],
["setting_2",150.0,"red"],
["setting_3",30.0,"green"],
["setting_4",11.0,"blue"]
]
}
How do I find the 'color' for the setting 'setting_4'? Acceptable solutions would either be am easy way to access the data, or a function to transform this into an exploded key/value array like
[
setting_1_value: '100',
setting_1_color: 'yellow',
setting_2_value: "150"
...
]
You can use this code to put the data into the type of data structure that you asked for:
var response = {"COLUMNS":["SETTING_NAME","SETTING_VALUE","COLOR"],
"DATA":[["setting_1",100.0,"yellow"],["setting_2",150.0,"red"],
["setting_3",30.0,"green"],["setting_4",11.0,"blue"]]};
var data = response.DATA;
var columns = response.COLUMNS;
var hash = {}, item, name, i;
var cols = {};
// remember order of columns
for (i = 0; i < columns.length; i++) {
cols[columns[i]] = i;
}
// fetch data from correct column
for (i = 0; i < data.length; i++) {
item = data[i];
name = item[cols["SETTING_NAME"]];
hash[name + "_value"] = item[cols["SETTING_VALUE"]];
hash[name + "_color"] = item[cols["COLOR"]];
}
hash.num = data.length;
As you requested, this gives you a data structure like this so you can directly read any value you want:
{
"setting_1_value":100,
"setting_1_color":"yellow",
"setting_2_value":150,
"setting_2_color":"red",
"setting_3_value":30,
"setting_3_color":"green",
"setting_4_value":11,
"setting_4_color":"blue",
"num":4
}
jsFiddle here: http://jsfiddle.net/jfriend00/HZmYN/ that generated this result.
Personally, I would rather use this code to parse it into this type of data structure:
var response = {"COLUMNS":["SETTING_NAME","SETTING_VALUE","COLOR"],
"DATA":[["setting_1",100.0,"yellow"],["setting_2",150.0,"red"],
["setting_3",30.0,"green"],["setting_4",11.0,"blue"]]};
var data = response.DATA;
var columns = response.COLUMNS;
var newData = [], item, obj, i, num, match;
var cols = {};
// remember order of columns
for (i = 0; i < columns.length; i++) {
cols[columns[i]] = i;
}
for (i = 0; i < data.length; i++) {
item = data[i];
obj = {};
obj.value = item[cols["SETTING_VALUE"]];
obj.color = item[cols["COLOR"]];
obj.name = item[cols["SETTING_NAME"]];
match = obj.name.match(/\d+$/);
if (match && match.length > 0) {
obj.settingNumber = parseInt(match[0], 10);
}
newData.push(obj);
}
// now sort the array by the number in the name setting
newData.sort(function(a, b) {
return(a.settingNumber- b.settingNumber);
});
And generates this data structure:
[
{"value":100,"color":"yellow","name":"setting_1","settingNumber":1},
{"value":150,"color":"red","name":"setting_2","settingNumber":2},
{"value":30,"color":"green","name":"setting_3","settingNumber":3},
{"value":11,"color":"blue","name":"setting_4","settingNumber":4}
]
Illustrated in this jsFiddle: http://jsfiddle.net/jfriend00/A23Jd/.
The reason I prefer this structure, is you can more easily access the "n" settings as an array of objects:
newData[0].color
newData[0].value
newData[0].name
newData[1].color
....
And, it's easier to iterate through the various settings
Using $.grep will allow you to access the data without mapping them before:
var json={"COLUMNS":["SETTING_NAME","SETTING_VALUE","COLOR"],
"DATA":[["setting_1",100.0,"yellow"],
["setting_2",150.0,"red"],
["setting_3",30.0,"green"],
["setting_4",11.0,"blue"]]}
alert($.grep(json.DATA, function(item){return(item[0]=='setting_4');})[0][2])//returns 'blue'
//or using the labels provided by COLUMNS:
alert($.grep(json.DATA,
function(a){return(a[0]=='setting_4');})[0][$.inArray('COLOR',json.COLUMNS)])
You can do this with a simple for loop:
var obj = {"COLUMNS":["SETTING_NAME","SETTING_VALUE","COLOR"],
"DATA":[["setting_1",100.0,"yellow"],["setting_2",150.0,"red"],
["setting_3",30.0,"green"],["setting_4",11.0,"blue"]]};
for(var i = 0; i < obj.DATA.length; i++)
{
var row = obj.DATA[i]
if (row[0] == 'setting_4')
{
console.log(row[2]);
break;
}
}
Prints:
blue
You could simply reduce that list of DATA:
DATA.reduce(function (value, item) { if (item[0] === "setting_4") return item[2] })
You could wrap that whole thing into a function for easier use, passing in the "setting_4" part. E.g.
var getColour = function (id) {
return DATA.reduce(function (value, item) {
if (item[0] === id) return item[2]
})
}
UPDATE: you could zip the two lists together, perhaps that would make access easier?
obj['DATA'].map(function (row) {
return obj['COLUMNS'].reduce(function (memo, columnName, index) {
memo[columnName] = row[index]
return memo
}, {})
})
This will return something like the following:
[{
COLOR: "yellow",
SETTING_NAME: "setting_1",
SETTING_VALUE: 100
}]
A generic algorithm for translating the dataset into a more-easily-addressed structure.
var json = {
"COLUMNS": [
"SETTING_NAME",
"SETTING_VALUE",
"COLOR"],
"DATA": [
["setting_1",100.0,"yellow"],
["setting_2",150.0,"red"],
["setting_3",30.0,"green"],
["setting_4",11.0,"blue"]
]
};
function translateJSON(json) {
var oHash = {};
var data = json['DATA'];
var cols = json['COLUMNS'];
for(var i = 0, imax = data.length; i < imax; i++) {
var row = data[i]; // shorthand
for(var j = 1, jmax = cols.length; j < jmax; j++) {
var c = cols[j]; // shorthand
oHash[(row[0] + '_' + c.replace(/[^_]+_/, '')).toLowerCase()] = row[j];
}
}
return oHash;
}
var h = translateJSON(json);
console.log(h['setting_4_color']);
Edit: updated the code. translateJSON will transform the JSON into the data structure you described, for easier property access. If you anticipate needing to access more than one property from the same JSON payload, it will be much more efficient to do a one-time transform before data access than to use something like $.grep, and much less terse than doing the column-name cross-referencing by hand.
That said, I don't think the target data structure you asked for is necessarily the best one. Assuming you can't change the structure of the JSON payload, it would still probably be better to transform that into something like:
data = {
'setting_1': { 'value': 100.0, 'color': 'yellow' },
'setting_2': { 'value': 150.0, 'color': 'red' }
...
};