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 } }
Related
I am doing the following:
$.getJSON(url,function(data){
var totalQueries = data.length;
$.each(data, function(i, item) {
But this one looks like to be wrong:
var totalQueries = data.length;
As by the end of it I check for the last item and it never happens:
if (i === totalQueries - 1) {
myId = item.pageid;
console.log(myId);
newQuery();
}
data is object use Object.keys(data).length; to count and here you object look like,
i is parse
{
"parse": {
"title": "Colegio Nueva Granada",
"pageid": 2340380,
"text": {
"*": "<div class=...."
},
"langlinks": []
}
}
Firs of all, I am newbie with Javascript and I think it is from about two hours that I am trying to understand this issue.
I have some objects (nested to one other object) where one property (called years) have this value: "1972-1974", for example. The value may change, but what remains the same is the presence of -. Object that have this property (year) with the value - need to be replicated, changing only year. If the value is "1972-1974" I want three object with value 1972, 1973 and 1974 in the year property (other property does not change).
Example of data structure.
{
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
"features": [
{
"type": "Feature",
"properties": {
"years": "1972-1974",
}
},
This is my attempt to solve my requiriment:
function formatYears(data) {
data.forEach(
function(d, index) {
if(typeof d.properties.years === "string" && d.properties.years.includes("-")) {
var temp = d.properties.years.split("-");
var count = temp[temp.length - 1] - temp[0];
d.properties.years = parseInt(temp[0]);
for(var i = 0; i < count; i++) {
var newData = jQuery.extend({}, d);
newData.properties.years = parseInt(temp[0]) + i + 1;
data.push(newData);
}
}
}
)
}
I call this function with
formatYears(json.features);
where json store all data previusly loaded.
I do not know why but all new objects have as years property 1974, in our example.
I tried to debug it and newData.properties.years take the right value (1973 and then 1974), but newData after data.push(newData) does not hold 1973 and 1974, but always 1974.
UPDATE:
Add link to json.
UPDATE 2:
Solved.
function formatYears(data) {
data.forEach(
function(d, index) {
if(typeof d.properties.years === "string" && d.properties.years.includes("-")) {
var temp = d.properties.years.split("-");
var count = temp[temp.length - 1] - temp[0];
d.properties.years = parseInt(temp[0]);
for(var i = 0; i < count; i++) {
var newData = jQuery.extend(true, {}, d);
newData.properties.years = parseInt(temp[0]) + i + 1;
data.push(newData);
}
}
}
)
}
Why?
Simple for loop:
function formatYears(features) {
features.forEach(function(feature){
var fromto = feature.properties.years.split('-');
var years = [];
for (var y = +fromto[0]; y <= fromto[1]; ++y)
years.push(y);
feature.properties.years = years;
return years;
});
}
var f = [
{
"type": "Feature",
"properties": {
"years": "1972-1974",
}
},
{
"type": "Feature",
"properties": {
"years": "1975-1978",
}
}];
function formatYears(features) {
features.forEach(function(feature){
var fromto = feature.properties.years.split('-');
var years = [];
for (var y = +fromto[0]; y <= fromto[1]; ++y)
years.push(y);
feature.properties.years = years;
});
}
formatYears(f)
console.log(f.map(f => f.properties.years))
I have made some changes to your js code
function formatYears(data) {
var out = [];
data.forEach(
function(d, index) {
if(typeof d.properties.years === "string" && d.properties.years.includes("-")) {
var temp = d.properties.years.split("-");
var count = (parseInt(temp[1],10) - parseInt(temp[0],10)) + 1;
//d.properties.years = parseInt(temp[0]);
for(var i = 0; i < count; i++) {
var newData = jQuery.extend(true, {}, d);
newData.properties.years = parseInt(temp[0], 10) + i;
console.log(newData);
out.push(newData);
}
}
}
)
console.log(out);
}
and when I am calling this with a data like this
var data = {
"features": [
{
"type": "Feature",
"properties": {
"years": "1972-1974",
}
},
{
"type": "Feature",
"properties": {
"years": "2007-2008",
}
},
{
"type": "Feature",
"properties": {
"years": "2010-2011",
}
}
]
};
its working fine.
Solved.
function formatYears(data) {
data.forEach(
function(d, index) {
if(typeof d.properties.years === "string" && d.properties.years.includes("-")) {
var temp = d.properties.years.split("-");
var count = temp[temp.length - 1] - temp[0];
d.properties.years = parseInt(temp[0]);
for(var i = 0; i < count; i++) {
var newData = jQuery.extend(true, {}, d);
newData.properties.years = parseInt(temp[0]) + i + 1;
data.push(newData);
}
}
}
)
}
So I have little bit of a tricky problem right here:
I'm getting 5x2 arrays from this function
for (var i = 0; i < 5; i++) {
var name = $('.lesson-space:eq( ' + i + ' ) > .lesson').map(function(){return $(this).data('name');}).get();
var color = $('.lesson-space:eq( ' + i + ' ) > .lesson').map(function(){return $(this).data('color');}).get();
};
For each of these 5 repeats I want to put the two arrays into an object like this
{
"name": "deutsch",
"color": "red"
},
{
"name": "mathe",
"color": "blue"
},
{
"name": "sport",
"color": "darkblue"
},
{
"name": "franz",
"color": "yellow"
}
These objects should be put now into in array. So in the end I would like to have 5 arrays (from the first code snipped) put into one array like this
[
[
...
],[
...
],[
...
],[
...
],[
...
]
]
I know it's a bit complicated...
As I understood you want to do something like this
var res = [],
data = {};
for (var i = 0; i < 5; i++) {
data = $('.lesson-space:eq( ' + i + ' ) > .lesson').map(function () {
var name = $(this).data('name');
var color = $(this).data('color');
if (!name || !color) {
return null;
}
return {
name: name,
color: color
}
}).get();
res.push(data);
}
I'm not sure I've understood you requirements correctly, however I think this is what you're looking for
var result = [];
for (var i = 0; i < 5; i++) {
result.push($('.lesson-space:eq('+i+') > .lesson').get().map(function(){
return {
name: $(this).data('name'),
color: $(this).data('name')
};
}));
}
console.log(result);
This should work
var mainArray = [];
for (i = 0; i < name.length; i++) {
var o = {};
o.name = name[i];
o.color = color[i];
mainArray.push([o])
}
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 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;
}