I have a generated JSON file that I would like to transform. Is there an easy way to transform the "id"/"value" form of this JSON to a proper key/value JSON object, without using any frameworks?
These lines:
"value":"chrome",
"id":"foo"
would convert to:
"foo": "chrome"
Input JSON:
{"row":[
{
"column":[
{
"value":"chrome",
"id":"foo"
},
{
"value":0,
"id":"bar"
},
{
"value":"baz1",
"id":"baz"
},
{
"value":0,
"id":"legacy"
}
]
},
{
"column":[
{
"value":"firefox",
"id":"foo"
},
{
"value":0,
"id":"bar"
},
{
"value":"baz2",
"id":"baz"
},
{
"value":0,
"id":"legacy"
}
]
}
]
}
Desired JSON:
{"row":[
{
"foo":"chrome",
"bar":0,
"baz":"baz1",
"legacy":0
},
{
"foo":"firefox",
"bar":0,
"baz":"baz2",
"legacy":0
}
]
}
Here is the solution:
var result = {"row": []}
for (var i = 0; i < input["row"].length; i++) {
var object = {};
var column = input["row"][i]["column"];
for (var j = 0; j < column.length; j++) {
object[column[j]["id"]] = column[j]["value"];
}
result.row.push(object);
}
console.log(result);
input variable refers to your initial JSON object.
var input = {"row":[
{
"column":[
...
here is my function, i was typing it out allready before ioseb posted his answer so i figured it post it as well, it's linted and everything
function transform(data) {
"use strict";
var x, i, row, column, colNumb, out = {rows : []}, rownum = data.row.length;
for (x = 0; x < rownum; x += 1) {
row = {};
column = data.row[x].column;
colNumb = column.length;
for (i = 0; i < colNumb; i += 1) {
row[column[i].id] = column[i].value;
}
out.rows.push(row);
}
return out;
}
Related
I'm trying to perform MapReduce on this kind of data set:
{
"_id": "599861ce7ce78cd973746906",
"name": "Macias Rosario",
"col": [
{
"date": "15/03/2016",
"name": "MAGNEATO",
"amount": 313.86
},
{
"date": "08/08/2016",
"name": "FORTEAN",
"amount": 151.06
},
{
"date": "05/11/2014",
"name": "ECRATIC",
"amount": 291.68
}
]
}
Goal is to sum up all amount for name Macias Rosario. Currently I did with my code to group all by subelements this.col.name on this way:
mapper = Code("""
function() {
for (var index = 0; index < this.col.length; ++index) {
var col = this.col[index];
emit(col.name, col.amount );
}
}
""")
reducer = Code("""
function(key, values) {
var total = 0;
for( var i = 0; i < values.length; ++i){
total += values[i];
}
return value.price;
}
""")
result = collection.map_reduce(mapper, reducer, "myresult")
Has anyone have some idea how to reference, or group by this.name and not this.col.name because I don't know anymore and I'm driving nuts?
PS don't suggest me to use aggregate, did that way, want to try on this way also :)
Kind regards,
I hope the following code helps (works in pymongo as well)
This is my map function:
var mapFunction = function() {
for (var idx = 0; idx < this.col.length; idx++) {
var key = this.name;
var value = { amount : this.col[idx].amount };
emit(key, value);
}
};
And the following is my reduce function:
var reduceFunction = function(key, amountVl) {
reduceVal = { amount : 0 };
for (var idx = 0; idx < amountVl.length; idx++) {
reduceVal.amount += amountVl[idx].amount;
}
return reduceVal;
}
With your sample data it produces:
{ "_id" : "Macias Rosario", "value" : { "amount" : 756.6 } }
I have list of jobs that needs to be perform based on the data and device.
This is my sample data
device = [ device0, device1, device2 ]
device0 = {
group: [MATCH1, MATCH2]
}
device1 = {
group: [MATCH1, MATCH2, MATCH3]
}
device2 = {
group: [MATCH2, MATCH3]
}
data = {
"destination": "destination",
"text": "Test send message",
"hlr": "MATCH2"
}
How can i fix my code so that my data can match and perform task to device. I'm sorry this is my first question. I'm still learning programming and I'm not fluent in english.
This is my sample code :
const jobs = []
jobs.push(data)
if (jobs.length > 0) {
let task= jobs.shift()
device.push(device.splice(0, 1)[0]); // swap device position
dataLoop: for (var i = 0; i < device.length; i++) {
itemLoop: for (var j = 0; j < device[0].group.length; j++) { // cycle through until find match
if (device[0].group[j].toString() === data.hlr.toString()) {
console.log(device[0].group[j] + ':' + data.hlr.toString()); // output should be MATCH2 : MATCH2
break dataLoop;
}
}
device.push(device.splice(0, 1)[0]);
}
device[0].sendData({ // using first device to perform task
receiver: data.destination,
text: data.text,
request_status: true
}, function(err, ref) {
setTimeout(function() {
if (err) { console.log(err) }
console.log(ref)
}, 5000)
});
}
Theres a typo:
itemLoop: for (var j = 0; j < device[i].group.length; j++) {
must be
itemLoop: for (var j = 0; j < device[0].group.length; j++) { //
I am trying to iterate over nested children of an object, but need have a delay after every child. Normally I would just write a recursive function and use that to iterate over an object, but this happens near instantly. How can I do this with a delay?
I thought about saving the index in a variable and accessing children using that, then increasing the index every time a setInterval is run, but how can this be expanded to take nesting into account?
Function to iterate:
function iter(obj) {
for (var i = 0; i < obj.length; i++) {
console.log(obj[i].command);
if (typeof obj[i].contains == "object") {
iter(obj[i].contains);
}
}
}
iter(object);
Example object:
[
{
"command":"do (5)",
"contains":[
{
"command":"move.up()",
"contains":false
},
{
"command":"move.left()",
"contains":false
},
{
"command":"if (kind == \"item\")",
"contains":[
{
"command":"move.down()",
"contains":false
}
]
},
{
"command":"move.right()",
"contains":false
}
]
}
]
First create a flat array from the hierarchy:
function iter(obj) {
var result = [];
for (var i = 0; i < obj.length; i++) {
result.push(obj[i]);
if (typeof obj[i].contains == "object") {
result = result.concat(iter(obj[i].contains));
}
}
return result;
}
var items = iter(object);
Now you can iterate the array with a timer and an index:
var index = 0;
var timer = window.setInterval(function(){
if (index < items.length) {
console.log(items[index].command);
index++;
} else {
window.clearInterval(timer);
}
}, 1000);
Demo:
var object = [
{
"command":"do (5)",
"contains":[
{
"command":"move.up()",
"contains":false
},
{
"command":"move.left()",
"contains":false
},
{
"command":"if (kind == \"item\")",
"contains":[
{
"command":"move.down()",
"contains":false
}
]
},
{
"command":"move.right()",
"contains":false
}
]
}
];
function iter(obj) {
var result = [];
for (var i = 0; i < obj.length; i++) {
result.push(obj[i]);
if (typeof obj[i].contains == "object") {
result = result.concat(iter(obj[i].contains));
}
}
return result;
}
var items = iter(object);
var index = 0;
var timer = window.setInterval(function(){
if (index < items.length) {
log(items[index].command);
index++;
} else {
window.clearInterval(timer);
}
}, 1000);
function log(str) {
document.getElementById('log').innerHTML += str + '<br>';
}
<div id="log"></div>
Trying to split a javascript object in to a hash array.. I have to split the contents inside the array based on the occurrence of symbol"|"
my input array looks like
{
"testFieldNames": ["testNumber", "testName", "testDate1", "testDate2"]
},
"data": [
"4|Sam|2012-02-10T00:00Z",
"0|Wallace|1970-01-01T00:00Z|2012-02-10T00:00Z"
]
};
and the expected output is [{"testNumber" : "4", "testName" : "Sam", "testDate1" : "2012-02-10T00:00Z", "testDate2" : "0"},{"testNumber" : "0", "testName" : "Wallace", "testDate1" : "1970-01-01T00:00Z", "testDate2" : "2012-02-10T00:00Z"}]
This is what I've tried.. but it is not complete.
http://jsfiddle.net/Dwfg6/1/
var header = responseData.header.testFieldNames,
length = header.length,
result;
result = responseData.data.map(function(el) {
var ret = {}, data = el.split('|'), i;
for (i=0; i < length; i++) {
ret[header[i]] = data[i];
}
return ret;
});
console.log(result);
The demo. (Note: you may use jQuery.map methods instead for old browsers.)
You were close...
http://jsfiddle.net/Dwfg6/4/
var responseData = {
"header": {
"testFieldNames": ["testNumber", "testName", "testDate1", "testDate2"]
},
"data": [
"4|Sam|2012-02-10T00:00Z|2012-02-10T00:00Z",
"0|Wallace|1970-01-01T00:00Z|2012-02-10T00:00Z"
]
};
function buildData(fields, data) {
var output = [];
if (fields && fields.length && data && data.length) {
for (var i = 0; i < data.length; i++) {
var row = data[i].split("|");
output[i] = {};
while (row.length) {
output[i][fields[4 - row.length]] = row.shift();
}
}
}
return output;
}
console.log(buildData(responseData.header.testFieldNames, responseData.data));
fiddle : http://jsfiddle.net/FjJse/1/
My answer:
fiddle
function mapData (data) {
'use strict';
var result=[];
var i, j;
var values = [];
var resultObj;
for(i=0; i < data.testFieldValues.length; i += 1) {
values = data.testFieldValues[i].split("|");
resultObj = {};
for(j = 0; j < data.testFieldNames.length; j += 1) {
resultObj[data.testFieldNames[j]] = values[j];
}
result.push(resultObj);
}
return result;
}
//$(document).ready(function() {
// 'use strict';
var data = {testFieldNames: ["testNumber", "testName", "testDate1", "testDate2"],
testFieldValues: [
"4|Sam|2012-02-10T00:00Z|2012-02-10T00:00Z",
"0|Wallace|1970-01-01T00:00Z|2012-02-10T00:00Z"
]
};
console.log(mapData(data));
//});
/*Expected Output [{"testNumber" : "4", "testName" : "Sam", "testDate1" : "2012-02-10T00:00Z", "testDate2" : "2012-02-10T00:00Z"},{"testNumber" : "0", "testName" : "Wallace", "testDate1" : "1970-01-01T00:00Z", "testDate2" : "2012-02-10T00:00Z"}]*/
Hit F12 in Chrome to see console, or open FireBug in FireFox or LadyBug in Opera, etc.
I have the following JavaScript:
var djs = function (ob) {
return {
remove: function () { //removes element
if (is_array(ob)) {
for (var i = 0; i < ob.length; i++)
ob[i].parentNode.removeChild(ob[i]);
} else {
ob.parentNode.removeChild(ob);
}
},
empty: function () { //makes element empty
if (is_array(ob)) {
for (var i = 0; i < ob.length; i++)
ob[i].innerHTML = "";
} else {
ob.innerHTML = ""
}
},
html: function (str) { //gets or sets innerHTML
if (str) {
if (is_array(ob)) {
for (var i = 0; i < ob.length; i++)
ob[i].innerHTML = str;
} else {
ob.innerHTML = str;
}
} else {
if (is_array(ob)) {
for (var i = 0; i < ob.length; i++)
rob += ob[i].innerHTML;
return rob;
} else {
return ob.innerHTML;
}
}
}
}
}
Here every time I am checking whether ob is an array or not and executing code. I want to minimize this, like instead of:
if (is_array(ob)) {
for (var i = 0; i < ob.length; i++)
ob[i].parentNode.removeChild(ob[i]);
} else {
ob.parentNode.removeChild(ob);
}
I want to use a function like, doEval(ob,code,return), in this case,
doEval(ob,"parentNode.removeChild("+ob+")",NULL);
"return" parameter will return if I specify any like innerHTML. Can any one help?
Don't repeat is_array check:
var djs=function(ob) {
if (!is_array(ob)) ob = [ob];
#SHiNKiROU is right of course, but just to provide an example of how to solve your problem with higher-order functions:
function doToAll(ob, callback) {
if(is_array(ob)) {
for (var i = 0; i < ob.length; i++) {
callback(ob[i]);
}
} else {
callback(ob);
}
}
...
remove:function(){ //removes element
doToAll(ob, function(actualOb) { actualOb.parentNode.removeChild(actualOb); });
},
...
But again, use #SHiNKiROU:s answer for this particular case.
Try this:
function doEval(a, b, c) {
if(is_array(a)) {
eval(b);
} else {
eval(c);
}
}
NULL doesn't exist by the way, it is null.