Store object properties in a 2d array - google-apps-script

I have an array of objects that I need to convert to a 2d array so I can write to a Google spreadsheet where each property is written to a cell. I have the function below:
function objectsToArray(objects) {
var outPutArray = createArray(objects.length, objects[0].length);
for (var i in objects) {
for (var j in objects[i]) {
if (objects.hasOwnProperty(i)) {
outPutArray[i][j] = objects[i][j];
}
}
}
return outPutArray;
}
example object:
object {
name: John
phone: 555-5555
email: john#john.com
}
The problem is that instead of putting the properties value in the array element (outputArray should look like [[John, 555-5555, john#john.com],[..., ..., ...]] it adds the properties to each array element.

In the first part of your function,
function objectsToArray(objects) {
var outPutArray = createArray(objects.length, objects[0].length);
it looks like you are assuming objects is already a 2D array. I'm going to assume that objects is a 1D array of objects like this. [{prop:value...},{...},{...}].
Now what you want to do is generate 2 numerical indices from this data. You will want to ensure that "column 1" of the 2D array is the same property for all objects.
So your first for loop should be over the properties. Also, keep an index so you know what number property you are on.
var j = 0;
for (var prop in objects[0]) {
Then you should do a loop over all the objects. So the idea is that first you will select "name", then go through all the objects, adding the "name" field to the 2D array for each object.
for (var i in objects) {
outPutArray[i][j] = objects[i][prop];
}
j++;
}
I think the main issue that you were seeing is because you weren't using numeric indices. (var j in objects[i]: this defines j as a property, such as "name", not a numeric index, like you were expecting).

Here's one way...
function myFunction() {
var objects = {};
objects[0] = {"name": "John", "phone": "555-5555", "email": "john#john.com"};
objects[1] = {"name": "Mary", "phone": "444-4444", "email": "mary#mary.com"};
var outputArrary = objectsToArray(objects);
Logger.log(outputArrary);
}
function objectsToArray(objects) {
var outputArray = [];
for (var i in objects)
outputArray.push([objects[i].name, objects[i].phone, objects[i].email]);
return outputArray;
}

Related

Get key value from the list of JSON in NodeJS

I am receiving the JSON object as a list of objects:
result=[{"key1":"value1","key2":"value2"}]
I am trying to retrieve the values from this list in Node.js. I used JSON.stringify(result) but failed. I have been trying to iterate the list using for(var key in result) with no luck, as it prints each item as a key.
Is anyone facing a similar issue or has been through this? Please point me in the right direction.
If your result is a string then:
var obj = JSON.parse(result);
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
console.log(obj[keys[i]]);
}
Lookslike you are pointing to wrong object.
Either do like
var result = [{"key1":"value1","key2":"value2"}];
for(var key in result[0]){ alert(key);}
or
var keys = Object.keys([{"key1":"value1","key2":"value2"}][0]);
alert(keys);
Okay, assuming that result here is a string, the first thing you need to do is to convert (deserialize) it to a JavaScript object. A great way of doing this would be:
array = JSON.parse(result)
Next you loop through each item in the array, and for each item, you can loop through the keys like so:
for(var idx in array) {
var item = array[idx];
for(var key in item) {
var value = item[key];
}
}
Wouldn't this just be:
let obj = JSON.parse(result);
let arrValues = Object.values(obj);
which would give you an array of just the values to iterate over.
A little different approach:
let result=[{"key1":"value1","key2":"value2"}]
for(let i of result){
console.log("i is: ",i)
console.log("key is: ",Object.keys(i));
console.log("value is: ",Object.keys(i).map(key => i[key])) // Object.values can be used as well in newer versions.
}
try this code:
For result=[{"key1":"value1","key2":"value2"}]
Below will print the values for Individual Keys:
console.log(result[0].key1)
console.log(result[0].key2)
This is for JsonObject (not JsonArray per se). p is your jsonobject the key pairs are key and p[key]
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
for (var key in p) {
if (p.hasOwnProperty(key)) {
console.log(key + " -> " + p[key]);
}
}

Changing JSON array to get smaller messages?

When using JSON to send an array of objects from the same class the objects fields are repeated many times, often unnecessarily, and the message becomes very long for arrays with big length. To my knowledge, there is no way to remove the field's repetition using only JSON. So I'm looking for a solution that solves the encoding and decoding of arrays without repeating the fields names.
As an example, the array below:
A:
[
{id:1;name:Name 1;description:Description 1},
{id:2;name:Name 2;description:Description 2},
...,
{id:N;name:Name N;description:Description N}
]
can be represented by:
B:
{
fields:[id, name, description],
values:[
[1,Name 1,Description 1],
[2,Name 2,Description 2],
...,
[N,Name N,Description N]
]
}
spending lot less space in the case of arrays with big length.
But I need a solution that does this transformation (from A to B and B to A) automatically. It can use the B represantation, or a better, to reduce the message size by eliminating fields names.
Any solution?
You can do this by writing two simple javascript functions to encode and decode as you want. Some rules have to apply in order for this paterns to work:
There must be a valid JSON input data string, though you can use a
plain array with objects
All array elements must have the same object structure format
It does not wotk with child objects
Minify/Unminify object function:
function minifyObject(obj) {
var fields = Object.keys(obj[0]);
var values = [];
for(var record in obj) {
var value = [];
for(var field in fields) {
value.push(obj[record][fields[field]]);
}
values.push(value);
}
return {
fields: fields,
values: values
}
}
function unminifyObject(obj) {
var output = [];
for(var i = 0; i < obj.values.length; i++) {
var record = {};
for(var j = 0; j < obj.fields.length; j++) {
record[obj.fields[j]] = obj.values[i][j];
}
output.push(record);
}
return output;
}
var data = [
{"id":1, "name": "Name 1", "description": "Description 1"},
{"id":2, "name": "Name 2", "description": "Description 2"},
{"id":3, "name": "Name 3", "description": "Description 3"}
];
var minified = minifyObject(data);
console.log("Minified object\n", minified);
var unminified = unminifyObject(minified);
console.log("Unminified array\n", unminified);
This code can also be simplified using ES6.
You can also find my test JSON converter here: https://zikro.gr/dbg/so/20129724/

Unnesting json object

My sample json is
"multiList": [
{
"my_key" : "this is my key"
},
{
"my_text_box": "This is my text box"
},
]
How do I convert this to
{"my_key" : "this is my key"},
{my_text_box": "This is my text box"},
dynamically?
using jquery
Your question doesn't make sense. Are you asking to convert to two separate objects? A string representation of those two objects? Something else? I can do the first two:
var objOne = json.multiList[0];
var objTwo = json.multiList[1];
var objStr = JSON.stringify(json.multiList[0]) + ', '
+ JSON.stringify(json.multiList[1]);
If you want to add all of the separate properties into one object, you can just extend another object in a loop.
var obj = {};
json.multiList.forEach(function (elem) {
for (k in elem) {
if (elem.hasOwnProperty(k)) {
obj[k] = elem[k];
}
}
});
http://jsfiddle.net/ExplosionPIlls/t2xyd/
This makes no consideration for the overriding of properties in obj.

How to get numeric value from array in as3?

I have an array like this
var records:Object = {};
var arr:Array = [
records["nh"] = { medinc:66303},
records["ct"] = { medinc:65958},
records["nj"] = { medinc:65173},
records["md"] = { medinc:64596},
records["kk"] = { medinc:61321}
];
arr.sortOn("medinc", Array.NUMERIC);
and I have the array sorted numerically. My question is how I can get the numeric value from each record? I want to use that value to set the width of different movie clips.
Something like
object1.width=(record for the [0] position in the array)
object2.width=(record for the [1] position in the array)
object3.width=(record for the [2] position in the array)
etc...
I hope this is clear enough. Thanks for your help!
trace(arr[0]['medinc']); // 61321
Basically, to address a certain field in the nested object, you address it as an associative array with an index of type String.

Slickgrid - Column Definition with Complex Objects

I have a Java object where the person object contains a displayName object. I have converted it to a JSON object for my JSP. The data looks like the following:
var people = [
{"id":52959,"displayName":{"firstName":"Jim","lastName":"Doe","middleName":"A"},"projectId":50003,"grade":"8","statusCode":"A","gradYear":2016,"buyer":false},
{"id":98765,"displayName":{"firstName":"Jane","lastName":"Doe","middleName":"Z"},"projectId":50003,"grade":"8","statusCode":"A","gradYear":2016,"buyer":true}
];
I want to bind my columns to the name properties that reside within the displayName object, but I am cannot get the column definition to recognize where the data resides. Here is an example of my firstName column definition:
{id: 'displayName.firstName', field: 'displayName.firstName', name: 'First Name',
width: 110, sortable: true, editor: TextCellEditor, formatter: SpaceFormatter,
cssClass: '', maxLength: 250, editable: true}
The view does not render the names although the data is there. Is it possible to bind a column to an object property that resides within another object? If so, what am I doing wrong?
Slickgrid doesn't support this capability by default, but you can workaround it by adding custom value extractor to your options object:
var options = {
dataItemColumnValueExtractor: function(item, columnDef) {
var names = columnDef.field.split('.'),
val = item[names[0]];
for (var i = 1; i < names.length; i++) {
if (val && typeof val == 'object' && names[i] in val) {
val = val[names[i]];
} else {
val = '';
}
}
return val;
}
}
var grid = new Slick.Grid($("#slickgrid"), data, columns, options);
The code is tested with slickgrid 2.0 and is working just fine. Unfortunately seems that slickgrid code is a bit inconsistent and editors don't take into account this option, so this solution is usable only if you will display the data without editing.
I know this is a bit old... but my work around is to do a pre-process on my items. Basically, flattening the model out:
var preProcessItems = function (items) {
var newItems = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
item['firstName'] = item['displayName']['firstName'];
newItems[i] = item;
}
return newItems;
};
/// when the value is updated on the flat structure, you can edit your deep value here
var fNameFormatter = function (row, cell, value, columnDef, dataContext) {
// datacontext.displayName.firstName = value;
return value ? value : "";
};
This problem seems to be more a of a data modeling issue though.