Javascript or Ruby. Reformat a JSON object - javascript

I need to turn this JSON object:
[
[
"email#email.com"
],
[
"email2#email.com"
],
[
"email3#email.com"
],
[
"email4#email.com"
]
]
Into this:
{
"data": [
{
"email": "email#email.com"
},
{
"email": "email2#email.com"
},
{
"email": "email3#email.com"
},
{
"email": "email4#email.com"
}
] }
How is this done?

Well, that's really just an array of arrays, but that's besides the point. Just loop through the array of arrays and push the relevant data onto the new array in your object:
var my_new_object = {};
my_new_object['data'] = [];
for (var i = 0; i < your_array.length; i++) {
my_new_object.data.push({"email": your_array[i][0]});
}
Working demo.

Javascript:
var original = [
[
"email#email.com"
],
[
"email2#email.com"
],
[
"email3#email.com"
],
[
"email4#email.com"
]
];
var output = {};
output.data = new Array();
for(var i=0;i<original.length;i++){
var o = new Object();
o.email = original[i][0];
output.data.push(o);
}

you can test it here:
http://jsfiddle.net/v3fnk/
var data=[["email#email.com"],["email2#email.com"],["email3#email.com"],["email4#email.com"]];
for (var i in data) {
for (var x in data[i]) {
$("#info").append(data[i][x] + '<br/>');
}
}

Related

unable to loop through nested array

I am trying to loop through the following array but did not succeed,
is my approach correct?
I have done many changes to my code it might be not as it was
my try :
var gender = ["men", "women"];
var category = [
"topwear",
"bottomwear",
"indianwear",
"westernwear",
];
for (var i = 0; i < categories.length; i++) {
for (var g = 0; g < gender.length; g++) {
for (j = 0; j < categories[i][gender[g]].length; j++) {
for (var c = 0; c < category.length; c++) {
console.log("=======category========", category[c]);
for (k = 0; k < categories[i][gender[g]][j][category[c]].length; k++) {
console.log(categories[i][gender[g]][j][category[c]][k]);
}
}
}
}
}
the array :
[
{
men: [
{
topwear: [
"men-topwear",
"men-tshirts",
"men-casual-shirts",
"men-formal-shirts",
"men-sweatshirts",
"men-sweaters",
"men-jackets",
"men-blazers",
"men-suits",
"rain-jacket",
],
},
{
bottomwear: [
"men-jeans",
"men-casual-trousers",
"men-formal-trousers",
"mens-shorts",
"men-trackpants",
"men-innerwear",
"men-briefs-and-trunks",
"men-boxers",
"men-innerwear-vests",
"men-nightwear",
"men-thermals",
],
},
],
},
{
women: [
{
indianwear: [
"women-kurtas-kurtis-suits",
"ethnic-tops",
"ethnic-wear-dresses-menu",
"women-ethnic-bottomwear?f=categories%3AChuridar%2CLeggings%2CSalwar",
"skirts-palazzos",
"saree",
"dress-material",
"lehenga-choli",
"dupatta-shawl",
"women-ethnic-wear-jackets",
"dresses?f=Gender%3Amen%20women%2Cwomen",
"jumpsuits?f=Gender%3Amen%20women%2Cwomen",
],
},
{
westernwear: [
"women-shirts-tops-tees",
"women-jeans-jeggings",
"women-trousers",
"women-shorts-skirts",
"women-shrugs",
"women-sweaters-sweatshirts",
"women-jackets-coats",
"women-blazers-waistcoats",
],
},
],
},
];
I need to get the names within the array.
coz i need to use it in the code which i am going to write inside the inner
most loop.
thanks in advance
Your code expects each object in the array to have both men and women properties. But these properties are in separate array elements. So you need to check whether the property exists before trying to loop over its elements. Otherwise you'll try to get the length of an undefined property.
Similarly, each object in the men or women array has just a single property, not all the properties in the category array.
Looping will be much easier if you assign variables to the current element of the array, so you don't need long expressions with lots of indexes like categories[i][gender[g]][j][category[c]][k]. And using forEach() will simplify this.
var gender = ["men", "women"];
var category = [
"topwear",
"bottomwear",
"indianwear",
"westernwear",
];
var categories = [{
men: [{
topwear: [
"men-topwear",
"men-tshirts",
"men-casual-shirts",
"men-formal-shirts",
"men-sweatshirts",
"men-sweaters",
"men-jackets",
"men-blazers",
"men-suits",
"rain-jacket",
],
},
{
bottomwear: [
"men-jeans",
"men-casual-trousers",
"men-formal-trousers",
"mens-shorts",
"men-trackpants",
"men-innerwear",
"men-briefs-and-trunks",
"men-boxers",
"men-innerwear-vests",
"men-nightwear",
"men-thermals",
],
},
],
},
{
women: [{
indianwear: [
"women-kurtas-kurtis-suits",
"ethnic-tops",
"ethnic-wear-dresses-menu",
"women-ethnic-bottomwear?f=categories%3AChuridar%2CLeggings%2CSalwar",
"skirts-palazzos",
"saree",
"dress-material",
"lehenga-choli",
"dupatta-shawl",
"women-ethnic-wear-jackets",
"dresses?f=Gender%3Amen%20women%2Cwomen",
"jumpsuits?f=Gender%3Amen%20women%2Cwomen",
],
},
{
westernwear: [
"women-shirts-tops-tees",
"women-jeans-jeggings",
"women-trousers",
"women-shorts-skirts",
"women-shrugs",
"women-sweaters-sweatshirts",
"women-jackets-coats",
"women-blazers-waistcoats",
],
},
],
},
];
categories.forEach(catItem =>
gender.forEach(genItem => {
if (catItem[genItem]) {
category.forEach(cat => {
console.log("=======category========", cat);
catItem[genItem].forEach(i => {
if (i[cat]) {
i[cat].forEach(x => console.log(x));
}
});
});
}
})
);

Adding values contained in an array of objects

How would I go about adding all the values within the object?
For example amoutpay": ["4222","1000"] would give me 5222
This is my object:
{
"amoutpay": [ "4222", "1000" ],
"amtpending": [ "778", "4000" ],
"totalcost": [ "5000", "5000" ],
"coursename": [ "Office Automation", "ajaba" ]
}
What I want is to add the values to variables. Would I use split?
var a =
var b =
var c =
You can use Array.prototype.reduce() as shown below:
var obj = {
"amoutpay": [ "4222", "1000" ],
"amtpending": [ "778", "4000" ],
"totalcost": [ "5000", "5000" ],
"coursename": [ "Office Automation", "ajaba" ]
},
a = obj.amoutpay.reduce(function(prevVal, curVal, curInd) {
return +prevVal + +curVal;
}),
b = obj.amtpending.reduce(function(prevVal, curVal, curInd) {
return +prevVal + +curVal;
}),
c = obj.totalcost.reduce(function(prevVal, curVal, curInd) {
return +prevVal + +curVal;
});
console.log( a, b, c );
Or you could go a step further and define your own array method, eg Array.prototype.sum():
var obj = {
"amoutpay": [ "4222", "1000" ],
"amtpending": [ "778", "4000" ],
"totalcost": [ "5000", "5000" ],
"coursename": [ "Office Automation", "ajaba" ]
};
Array.prototype.sum = function() {
return this.reduce(function( prv, cur, ind ) {
return +prv + +cur;
});
};
var a = obj.amoutpay.sum(),
b = obj.amtpending.sum(),
c = obj.totalcost.sum();
console.log( a, b, c );
var obj = {
"amoutpay": [ "4222", "1000" ],
"amtpending": [ "778", "4000" ],
"totalcost": [ "5000", "5000" ],
"coursename": [ "Office Automation", "ajaba" ]
}
var a = addValues(obj.amoutpay);
function addValues(arr) {
return arr.map(function(el) {
return Number(el);
}).reduce(function(prev, curr){
return prev + curr;
})
}
We iterate the object elements and for all arrays we check whether all the elements are numeric. If so, then add them as variables to the window object, so after the loop we will have an amoutpay variable for the input shown in the question. Note, that if a key happens to already be a variable, then this code will override it.
for (var key in obj) {
if (Array.isArray(obj[key])) {
var shouldAdd = true;
for (var index = 0; shouldAdd && index < obj[key].length; index++) {
if (isNaN(obj[key][index])) {
shouldAdd = false;
}
}
if (shouldAdd) {
window[key] = 0;
for (var index = 0; index < obj[key].length; index++) {
window[key] += parseFloat(obj[key][index]);
}
}
}
}

Javascript objects and array elements accessing

I am writing code for the drawing chart for support time series data by using VizGrammar JS library.
I am facing an issue with objects and arrays in javascript.
I am getting lots of Arrays,from that I need only first block of arrays only. How can I access that?
var data = [
{
...
},
"data": [
["test", 3.12 , Hello],
.....
],
}
];
innerDataValues = data[0].data;
console.log(innerDataValues);
$scope.getData = function(data) {
var innerData = '';
for (var i = 0 ; i < data.length; i++) {
for (var j = 0; j<data[i].data.length; j++) {
innerData += data[i].steps[j];
}
}
return innerData;
}
Here data am getting inside the argument is your Whole data , and the loop with var j is for your innerData . If you want to get particular data inside the innerData means you can put
innerData += data[i].steps[j].Whatever You want;
(Instead of $scope you can use 'this' also) Hope it will works .
You can obtain first block of each element by using array.map:
ES6 version
var innerDataValues = data.map(element => element.data);
ES5 version
var innerDataValues = date.map(function(el){ return el.data; })
Edit : that works with this exemple :
var data = [{
"prop" : {
"val" : 12,
"eval": 36
},
"data": [
["test", 3.12 ,"Hello"],
["toto", 18, "titi"]
]
},
{
"prop" : {
"val" : 25,
"eval": 64
},
"data": [
["prod", 3.13 ,"Hi"],
["john", 18, "mike"]
]
}
];
var innerDataValues = data.map(element => element.data);
console.log(innerDataValues); //[ [ [ 'test', 3.12, 'Hello' ], [ 'toto', 18, 'titi' ] ], [ [ 'prod', 3.13, 'Hi' ], [ 'john', 18, 'mike' ] ] ]

Object Array Formatting

I have an object in this format:
var request = {
"student": [
[
"name",
"age"
],
[
"Tom",
12
],
[
"Jack",
13
]
]
};
I want to transform it into this:
var request = {
"student": [
{
"name": "Tom",
"age": 12
},
{
"name": "Jack",
"age": 13
}
]
}
I tried doing it this way:
var response = [];
var keysCount = req.result[0].length;
var responseCount = req.result.length - 1;
var i = 0,
j = 0,
key;
for (j = 0; j < responseCount; j++) {
for (i = 0; i < keysCount; i++) {
key = req.result[0][i];
response[j][key] = req.result[j + 1][i];
}
}
return response;
But, it is not working as expected.
It's a matter of looping through the first array and creating an array of objects for all the remaining arrays, using values at matching indexes to create properties on object:
var request = {
"student": [
[
"name",
"age"
],
[
"Tom",
12
],
[
"Jack",
13
]
]
};
// Get the header array
var headers = request.student[0];
// Create the new array but mapping the other entries...
var newArray = request.student.slice(1).map(function(entry) {
// Create an object
var newEntry = {};
// Fill it in with the values at matching indexes
headers.forEach(function(name, index) {
newEntry[name] = entry[index];
});
// Return the new object
return newEntry;
});
console.log(newArray);
I would make a small function tabularize that takes an array of data where the first element is an array of headers, and the remaining elements are the rows
Code that follows uses ES6. If you need ES5 support, you can safely transpile this code using a tool like babel.
// your original data
var request = {
"student": [
[
"name",
"age"
],
[
"Tom",
12
],
[
"Jack",
13
]
]
};
// tabularize function
var tabularize = ([headers, ...rows])=>
rows.map(row=>
headers.reduce((acc,h,i)=>
Object.assign(acc, {[h]: row[i]}), {}));
// your transformed object
var request2 = {student: tabularize(request.student)};
// log the output
console.log(request2);
//=> {"student":[{"name":"Tom","age":12},{"name":"Jack","age":13}]}
Or you can create the request object with the intended shape by passing the tabular data directly into the tabularize function at the time of object creation
// tabularize function
var tabularize = ([headers, ...rows])=>
rows.map(row=>
headers.reduce((acc,h,i)=>
Object.assign(acc, {[h]: row[i]}), {}));
// your request object
var request = {
student: tabularize([
[
"name",
"age"
],
[
"Tom",
12
],
[
"Jack",
13
]
])
};
// log the output
console.log(request);
//=> {"student":[{"name":"Tom","age":12},{"name":"Jack","age":13}]}
Let's start off by writing a little function just to create an object from two arrays, one of keys and one of their values:
function makeObjectFromPairs(keys, values) {
var object = {};
for (var i = 0; i < keys.length; i++) {
object[keys[i]] = values[i];
}
return object;
}
// makeObjectFromPairs(['a', 'b'], [1, 2]) === {a: 1, b: 2}
Now we can use the first element of the students array as the keys, and each of the remaining elements as the values.
var keys = students[0];
var result = [];
for (var i = 1; i < students.length; i++) {
result.push(makeObjectFromPairs(keys, students[i]);
}
You could use Array#map etc. as an alternative for the loops, but perhaps this basic approach is more accessible.
Fixing your original code
Since you made a valiant effort to solve this yourself, let's review your code and see where you went wrong. The key point is that you are not initializing each element in your output to an empty object before starting to add key/value pairs to it.
for (j = 0; j < responseCount; j++) {
// Here, you need to initialize the response element to an empty object.
response[j] = {};
Another solution :
var request = {
"student": [
[
"name",
"age"
],
[
"Tom",
12
],
[
"Jack",
13
]
]
};
var response = {};
var students = [];
var responseCount = request.student.length - 1;
var j = 0,
key;
for (j = 0; j < responseCount; j++) {
var student = {};
request.student[0].forEach(function(name, index) {
student[name] = request.student[1 + j][index];
});
students.push(student)
}
response["students"] = students;
console.log(response); // {"students":[{"name":"Tom","age":12},{"name":"Jack","age":13}]}
Lodash solution
var keys = _.head(request.student);
var valueGroups = _.flatten(_.zip(_.tail(request.student)));
var studentObjects = valueGroups.map(function(values){
return values.reduce(function(obj, value, index){
obj[keys[index]] = value;
return obj;
}, {});
});
console.log(studentObjects);
https://jsfiddle.net/mjL9c7wt/
Simple Javascript solution :
var request = {
"student": [
[
"name",
"age"
],
[
"Tom",
12
],
[
"Jack",
13
]
]
};
var students = [];
for(var x = 1; x<request.student.length;x++)
{
var temp = { 'name' : request.student[x][0],
'age' : request.student[x][1]
}
students.push(temp);
}
request = { 'students' : students}
console.log(request);

JSON data transformation from table-like format to JSON?

I have data that's in this format:
{
"columns": [
{
"values": [
{
"data": [
"Project Name",
"Owner",
"Creation Date",
"Completed Tasks"
]
}
]
}
],
"rows": [
{
"values": [
{
"data": [
"My Project 1",
"Franklin",
"7/1/2015",
"387"
]
}
]
},
{
"values": [
{
"data": [
"My Project 2",
"Beth",
"7/12/2015",
"402"
]
}
]
}
]
}
Is there some super short/easy way I can format it like so:
{
"projects": [
{
"projectName": "My Project 1",
"owner": "Franklin",
"creationDate": "7/1/2015",
"completedTasks": "387"
},
{
"projectName": "My Project 2",
"owner": "Beth",
"creationDate": "7/12/2015",
"completedTasks": "402"
}
]
}
I've already got the column name translation code:
r = s.replace(/\%/g, 'Perc')
.replace(/^[0-9A-Z]/g, function (x) {
return x.toLowerCase();
}).replace(/[\(\)\s]/g, '');
Before I dive into this with a bunch of forEach loops, I was wondering if there was a super quick way to transform this. I'm open to using libraries such as Underscore.
function translate(str) {
return str.replace(/\%/g, 'Perc')
.replace(/^[0-9A-Z]/g, function (x) {
return x.toLowerCase();
})
.replace(/[\(\)\s]/g, '');
}
function newFormat(obj) {
// grab the column names
var colNames = obj.columns[0].values[0].data;
// create a new temporary array
var out = [];
var rows = obj.rows;
// loop over the rows
rows.forEach(function (row) {
var record = row.values[0].data;
// create a new object, loop over the existing array elements
// and add them to the object using the column names as keys
var newRec = {};
for (var i = 0, l = record.length; i < l; i++) {
newRec[translate(colNames[i])] = record[i];
}
// push the new object to the array
out.push(newRec);
});
// return the final object
return { projects: out };
}
DEMO
There is no easy way, and this is really not that complex of an operation, even using for loops. I don't know why you would want to use regex to do this.
I would start with reading out the column values into a numerically indexed array.
So something like:
var sourceData = JSON.parse(yourJSONstring);
var columns = sourceData.columns[0].values[0].data;
Now you have a convenient way to start building your desired object. You can use the columns array created above to provide property key labels in your final object.
var sourceRows = sourceData.rows;
var finalData = {
"projects": []
};
// iterate through rows and write to object
for (i = 0; i < sourceRows.length; i++) {
var sourceRow = sourceRows[i].values.data;
// load data from row in finalData object
for (j = 0; j < sourceRow.length; j++) {
finalData.projects[i][columns[j]] = sourceRow[j];
}
}
That should do the trick for you.

Categories