Object Array Formatting - javascript

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);

Related

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' ] ] ]

Pushing Javascript Object Inside An Array Using A For Loop

Hi I am trying push a javascript object inside an array in javascript using a for loop to iterate through the data. Here is how my code looks like.
var data = {"up": [{
"name": "jack",
"age" : 10
},
{
"name" : "jhon",
"age" : 12
}]};
var output = {};
var output_data = {
element: []
};
for (var key in data.up) {
output.user_name = data.up[key].name;
output_data.element.push(output);
}
console.log(output_data.element);
However as you can see in the example http://jsbin.com/fanazaxoda/edit?html,js,console only the second element is name 'jhon' is inserted in both occations. What am I doing wrong here? Please explain.
Move the output initialization inside for loop otherwise it push reference of object each time. Updating it's property may reflect in all array elements since all elements are referring the same object.
var output_data = {
element: []
};
for (var key in data.up) {
var output = {}; // create new empty object on each iteration
output.user_name = data.up[key].name;
output_data.element.push(output);
}
var data = {
"up": [{
"name": "jack",
"age": 10
}, {
"name": "jhon",
"age": 12
}]
};
var output_data = {
element: []
};
for (var key in data.up) {
var output = {};
output.user_name = data.up[key].name;
output_data.element.push(output);
}
console.log(output_data.element);

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.

JSON to filtered Array in JavaScript

I have this JSON string:
[
{
"pk": "alpha",
"item": [{
"child": "val"
}]
},
{
"pk": "beta",
"attr": "val",
"attr2": [
"child1"
]
},
{
"pk": "alpha",
"anotherkey": {
"tag": "name"
}
}
]
And I need to produce a filtered array without repeated PK, in the example above the last entry: "pk": "alpha","anotherkey": { ... should be eliminated from the output array. All this using JavaScript. I tried with the object JSON.parse but it returns many key,value pairs that are hard to filter for example "key=2 value=[object Object]".
Any help is greatly appreciated.
var data = JSON.parse(jsonString);
var usedPKs = [];
var newData = [];
for (var i = 0; i < data.length; i++) {
if (usedPKs.indexOf(data[i].pk) == -1) {
usedPKs.push(data[i].pk);
newData.push(data[i]);
}
}
// newData will now contain your desired result
var contents = JSON.parse("your json string");
var cache = {},
results = [],
content, pk;
for(var i = 0, len = contents.length; i < len; i++){
content = contens[i];
pk = content.pk;
if( !cache.hasOwnPropery(pk) ){
results.push(content);
cache[pk] = true;
}
}
// restuls
<script type="text/javascript">
// Your sample data
var dataStore = [
{
"pk": "alpha",
"item": [{
"child": "val"
}]
},
{
"pk": "beta",
"attr": "val",
"attr2": [
"child1"
]
},
{
"pk": "alpha",
"anotherkey": {
"tag": "name"
}
}
];
// Helper to check if an array contains a value
Array.prototype.contains = function(obj) {
var i = this.length;
while (i--) {
if (this[i] == obj) {
return true;
}
}
return false;
}
// temp array, used to store the values for your needle (the value of pk)
var tmp = [];
// array storing the keys of your filtered objects.
var filteredKeys = [];
// traversing you data
for (var i=0; i < dataStore.length; i++) {
var item = dataStore[i];
// if there is an item with the same pk value, don't do anything and continue the loop
if (tmp.contains(item.pk) === true) {
continue;
}
// add items to both arrays
tmp.push(item.pk);
filteredKeys.push(i);
}
// results in keys 0 and 1
console.log(filteredKeys);
</script>

Javascript or Ruby. Reformat a JSON object

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/>');
}
}

Categories