I have this Javascript json array object;
var dataJson=[ [{v:1},{v:90}],[{"v":2},{"v":"33.7000"}] ];
I want to append this array object dataJson to another object such that it looks like this;
var chartObject = {"cols": [
{id: "t", label: "t_label", type: "number"},
{id: "s", label: "s_label", type: "number"}
], "rows": [
{c:
[{v:1},{v:90}] //dataJson[0]
},
{c:
[{"v":2},{"v":"33.7000"}] ////dataJson[1]
}
]};
How do I use a for loop to insert dataJson elements into chartObject? I am sorry I am quite new to javascript and can't even produce some starting code. Thank you very much for any help.
Try this:
...
], "rows": dataJson.map(function(row) {return {c:row};})
};
Javascript objects are pretty amazing things. Just define a new field in chartObject as an array, and then push whatever json data you want into it. It looks you want rows to be an array of objects which have an identifier for each json object, but unless you explicitly want to name each dataJson with a string, then just use an indexed array:
chartObject["rows"] = [];
for(var i = 0; i < dataJson.length; i++) {
chartObject["rows"].push(dataJson[0]);
}
Now you can access each piece of data with:
chartObject["rows"][index]
And each field in the data with:
chartObject["rows"][index]["v"]
Using the simple and clean way:
var chartObject = {"cols": [
{id: "t", label: "t_label", type: "number"},
{id: "s", label: "s_label", type: "number"}
]};
var dataJson=[ [{v:1},{v:90}],[{"v":2},{"v":"33.7000"}] ];
chartObject["rows"] = []; // start with empty array
// iterate over first dataJson array
for(var i = 0, len = dataJson[0].length; i < len; i++){
// push in array `c` mapped to the i-th element of dataJson[0]
chartObject["rows"].push({c : dataJson[0][i]["v"]});
}
console.log(chartObject);
DEMO
Ignore those [object Object] in DEMO
Sample Output:
{
cols: [{
id: "t",
label: "t_label",
type: "number"
}, {
id: "s",
label: "s_label",
type: "number"
}],
rows: [{
c: 1
}, {
c: 90
}]
}
Related
Im facing a small issue in Javascript.
I have below Arrays.
var labels = ["labelOne", "labelTwo"];
var values1 = ["89", "9"];
var values2 = ["32", "78"];
Here we can place n number of values arrays like value3,value4....
Now how can i form an array of Objects by combining labels Array and their values are in values arrays. Im expecting the below output after combining above 3 arrays..
var mainArray = [{
label:"labelOne",
value:"89"
},
{
label:"labelTwo",
value:"9"
},
{
label:"labelOne",
value:"32"
},
{
label:"labelTwo",
value:"78"
}]
Can someone please help me to achieve the above output.
Thank you in advance
All that you need is a variable to know how many arrays should be added and access them in a loop using the advantage that Javascript lets you get them like this: window['variableName'] when they are defined in global scope.
var labels = ["labelOne", "labelTwo"];
var values1 = ["89", "9"];
var values2 = ["32", "78"];
var mainArray = [];
// Define a variable to know how many arrays should be added
var maxValues = 2;
function addValues(values) {
// Create new elements and push them into mainArray
mainArray.push({label:labels[0], value:values[0]});
mainArray.push({label:labels[1], value:values[1]});
}
// Do a loop from 1 to maxValues
for(let i = 1; i <= maxValues; i++) {
// Call the function with dynamic variable name
addValues(window['values' + i]);
}
console.log(mainArray);
If the order of your array isn't critical (and then, you might sort it later if it is), you can do like this:
const output = labels.map((label, index) => {
return [{ label, value: values1[index] }, { label, value: values2[index] }];
}).flat();
The map step, will give you an array like this:
[
[{ label: 'labelOne', value: 89 }, { label: 'labelOne', value: 32 }],
[{ label: 'labelTwo', value: 9}, { label: 'labelTwo', value: 78}]
]
By then calling flat, it'll transform it into:
[{ label: 'labelOne', value: 89 }, { label: 'labelOne', value: 32 }, { label: 'labelTwo', value: 9}, { label: 'labelTwo', value: 78}]
Which is what you wanted, from here you can sort the array if that matters for your use case.
I have an API endpoint that expects the following json string (this is an example).
{
"userid": "1234",
"bookshelf": "3",
"bookcount": "6",
"books":[
{"bookid": "1"},
{"bookid": "2"},
{"bookid": "3"},
{"bookid": "6"}
]}
The api accesses each in the following manner:
$userid = $data['userid'];
$bookshelf = $data['bookshelf'];
etc...
I can also loop through the books and get each bookid with:
$data['books'][$i]['bookid']
When I send the above json string via a tool like postman it works fine. I'm having trouble manufacturing this same json string on the javascript side. This is how I populate the data on the front end of my site.
var data = new Array();
data.push({ "userid": "1234" });
data.push({ "bookshelf": "3" });
data.push({ "bookcount": "6" });
data.push({ "books": selectedbooks }); // This is an array of bookid objects
The problem is whether I json.stringify it and send to the webserver and over to the api or have the webserver json_encode, I end up with numeric indexes that can only be accessed like $data[0]['userid']; once it's decoded by the api, which differs from how the api is working. This would require the json string to be assembled in an exact sequence if the api supported it.
How do I go about getting this data in the required format?
The numeric indexes are coming because you're preparing the data as an array, not an object. Arrays in JavaScript are indexed, not associative. Try:
var data = {
userid: 1234,
bookshelf: 3,
bookcount: 6,
books: selectedbooks
};
You need to create an object, not an array.
var data = {};
data["userid"] = "1234";
data["bookshelf"] = "3";
data["bookcount"] = "6";
data["books"] = selectedbooks; // This is an array of bookid objects
Your data is not supposed to be an array, it's an object. The only array is in the books property.
var data = {}
data.userid = "1234";
data.bookshelf = "3";
data.bookcount = "6";
data.books = selectedbooks;
or more succintly:
var data = {
userid: "1234",
bookshelf: "3",
bookcount: 6,
books: selectedbooks
};
You can easily transform your array into the expected object :
var arr = [
{"userid": "1234"},
{"bookshelf": "3"},
{"bookcount": "6"},
{
"books":[
{"bookid": "1"},
{"bookid": "2"},
{"bookid": "3"},
{"bookid": "6"}
]}
];
var obj = {} ;
arr.forEach(item => {
var key = Object.keys(item)[0];
obj[key] = item[key];
});
console.log(obj);
//{ userid: '1234',
// bookshelf: '3',
// bookcount: '6',
// books:
// [ { bookid: '1' },
// { bookid: '2' },
// { bookid: '3' },
// { bookid: '6' } ] }
I have an array of objects, say the object looks like following:
var row = {
data: 'test',
text: 'test'
};
I want to loop through the array and just get the object with text property.
What is the best way to do it?
So, I want to loop and the object should look like: row = {text: 'test'}
I tried something like below without luck:
arr.forEach(function (item){ //arr is the array of object
return {text: item.text};
});
Use Array.prototype.map for that:
var arr = [{
data: 'testData',
text: 'testText'
}];
var newArr = arr.map(function(item){
return {text: item.data};
});
The result will look like:
[{ text: 'testData' }]
If you want it to be [ {testText: 'testData' }] then:
var arr = [{
data: 'testData',
text: 'testText'
}];
var newArr = arr.map(function(item){
var obj = {};
obj[item.text] = item.data;
return obj;
});
As you want a object with single key value pair, you don't need to store in object form. You can save them as an array.
var array = [
{
text : "text",
data : "data"
},
{
text : "text1",
data : "data1"
}
]
var newArray = array.map(function(item){
return item.data;
});
your output will look like
['text','text1']
In my script, a function uses the values in my teststim array.
var teststim = ["A", "B", "C"]
And I want to give 'attributes' to these values, so that for example A has the attribute "name", B "birthday", ...
I need to find a way to have access to these attributes. I thought about something like this:
var teststim = {content: "A", attribute: "name"},
{content: "B", attribute: "birthday"},
{content: "C", attribute: "whatever"}
Maybe I'm close than I think, but I am not able to access the 'attribute' values corresponding to the content values. What am I missing?
You need an array of objects:
var teststim = [{content: "A", attribute: "name"},
{content: "B", attribute: "birthday"},
{content: "C", attribute: "whatever"}];
for (var i=0; i<teststim.length; i++) {
var obj = teststim[i];
if (obj.content=='C') {
alert(obj.attribute); // "whatever"
};
};
You can not give properties/attributes to the values of YOUR array.
Therefore, you must start with:
var arr = [
{content:'A'},
{content:'B'},
{content:'C'}
];
Now you can add new attributes, e.g.:
arr[0].attribute = '2';
If you want to map a value in the array to another (longer?) value, you can use:
var mapping = {"A" : "name",
"B" : "birthday",
"C" : "whatever"}
for(var i = 0, len = teststim.length; i < len; i++)
{
alert(mapping[teststim[i]]);
}
If not, then just have an array of objects:
var teststim = [{ 'content' : "A", 'attribute' : "name" },
{ 'content' : "B", 'attribute' : "birthday" },
{ 'content' : "C", 'attribute' : "whatever" }];
for(var i = 0, len = teststim.length; i < len; i++)
{
alert(teststim[i].attribute);
}
I made a small plnkr here to show what I am trying to achieve. I have a big dataset, where I like to sum the individual type to get a total.
I could think of iterating and adding the results to an object hash, but wonder more elegant way to solve it with underscore. I am using underscore.js, but never tried map reduce or other functional paradigm. Please update the plnkr to learn how to do this.
http://plnkr.co/edit/B5HGxhwvWsfvOR97z7TL?p=preview
var data = [ {'type': "A", 'val':2},
{'type': "B", 'val':3},
{'type': "A", 'val':1},
{'type': "C", 'val':5} ];
_.each(data, function (elm, index) {
console.log(elm);
});
/*
Desired output
out = [ {'type': "A", 'total':3},
{'type': "B", 'total':3},
{'type': "C", 'total':5} ];
*/
var data = [ { type: "A", val: 2 },
{ type: "B", val: 3 },
{ type: "A", val: 1 },
{ type: "C", val: 5 } ];
var groups = _(data).groupBy('type');
var out = _(groups).map(function(g, key) {
return { type: key,
val: _(g).reduce(function(m,x) { return m + x.val; }, 0) };
});
DEMO
Pretty much the same answer as #GregL, just with a bit more underscore:
summed_by_type = _(data).reduce(function(mem, d) {
mem[d.type] = (mem[d.type] || 0) + d.val
return mem
}, {})
pairs = _(summed_by_type).map(function(v,k) { return {type: k, total: v} })
The following will work, but I assume it is similar to what you had in mind. The advantage is that by using an object hash to store the totals, you are indexing on the type which means you don't have to iterate through the hash each time trying to find the object with the right type. Then you iterate through it once at the end to build up the final output array.
Plunkr is here.
Code is as follows:
var data = [ {'type': "A", 'val':2},
{'type': "B", 'val':3},
{'type': "A", 'val':1},
{'type': "C", 'val':5} ];
var totalPerType = {};
for (var i = 0, len = data.length; i < len; ++i) {
totalPerType[data[i].type] = totalPerType[data[i].type] || 0;
totalPerType[data[i].type] += data[i].val;
}
var out = _.map(totalPerType, function(sum, type) {
return { 'type': type, 'total': sum };
});
console.log('out = ', out);
EDIT: I have created a new plunkr that generates how fast this is even for a 1 million item array (with 6 possible types) here. As you can see from the console output, at least in Chrome Canary, it runs in about 1/3 second.
I have also done a jsPerf test for how much faster it is to use the intermediate hash, and it works out about 50% faster.