Merge arrays to object and object to array - javascript

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])
}

Related

Pymongo MapReduce as sum of subarray element

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 } }

Apparently assignment to proprierty of object does not work in javascript

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

Group or rearrange array elements based on a condition - javascript

I have an array called 'country' which looks like:
country=[
{
"name": "china",
"id": "country:china"
}, {
"name": "city1",
"id": "country:country1>city1"
}, {
"name": "city2",
"id": "country:country1>city2"
}, {
"name": "city3",
"id": "country:country1>city3"
}, {
"name": "korea",
"id": "country:korea"
}, {
"name": "australia",
"id": "country:australia"
}
]
I am looking at rearranging/grouping the above array as:
countryResult = [ china, country1(city1, city2, city3), korea, australia]
I have written the following code but this does not give me the desired result:
$scope.countryInfo = function(itemData){
var countryResult = [];
for(var i=0; i<itemData.length; i++){
var countryItem = itemData[i];
if(countryItem.id.indexOf('>') > -1){ //Found city
var itemId = countryItem.id.substr(0, countryItem.id.indexOf('>'));
for(var j=0; j<$scope.countryData.length; j++){
if($scope.countryData[j].id == itemId){
var _parentChild = $scope.countryData[j].name + "( " + countryItem.name + " ) ";
countryResult.push(_parentChild);
}
}
}
else{
countryResult.push(countryItem.name);
}
}
return countryResult;
}
The result is coming up like this - [ china, country1(city1), country1(city2), country1(city3)), korea, australia]
Please let me know how to achieve the expected array result.
EDIT: I am just looking at simplifying the array [ china, country1(city1), country1(city2), country1(city3)), korea, australia] to [ china, country1(city1, city2, city3), korea, australia]
I've used reduce with an initial object with a keys property to capture the positions of the elements:
function sorter(countty) {
var obj = country.reduce(function (p, c, i) {
var key, id = c.id.split(/[:>]/);
if (id.length === 3) {
key = id[1];
if (!p[key]) {
p[key] = [];
p.keys.push(key);
}
p[key].push(id[2]);
} else {
p.keys.push(c.name);
}
return p;
}, { keys: [] });
return obj.keys.map(function (el) {
return obj[el] ? el + '(' + obj[el].join(', ') + ')' : el;
});
}
sorter(country);
DEMO
You can use a temporary object and then map the object's properties to the wanted array.
var country = [{ "name": "china", "id": "country:china" }, { "name": "city1", "id": "country:country1>city1" }, { "name": "city2", "id": "country:country1>city2" }, { "name": "city3", "id": "country:country1>city3" }, { "name": "korea", "id": "country:korea" }, { "name": "australia", "id": "country:australia" }],
temp = {},
result;
country.forEach(function (a) {
var b = a.id.split(/\:|\>/g);
temp[b[1]] = temp[b[1]] || [];
if (b[2]) {
temp[b[1]].push(b[2]);
}
});
result = Object.keys(temp).map(function (k) {
if (temp[k].length) {
return k + '(' + temp[k].join(', ') + ')';
}
return k;
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
I wrote this bit of code to change your first array (in your "EDIT") into your second array, I'm not saying it's clean, but it works:
sorts the array, then tries to figure out if the countries match, and if they have cities that need to be merged...
//an array of countries, some of which include comma delimited cities wrappedin parentheses
var arrayPlaces = ["china", "country1(city1)", "korea", "country1", "country1(city2)", "country1(city3)", "australia", "korea", "home(delicious)", "home(nacho)", "home(plate)"];
//creates an alphabatized version of the array, to simplify finding matching countries
var arrayPlacesSorted = arrayPlaces.sort();
//defines a regular expression (to search for matches countries)
var hasCity = function (sTemp) {
var re = /\(/;
if (re.test(sTemp)) {
return true;
} else {
return false;
}
};
var countryRe = /(.*?)\(.*?\)/;
var cityRe = /.*?\((.*?)\)/;
//function that loops through array, checks for matching countries, combines/adds cities
var groupCities = function (aTemp) {
var currentCountry,
currentCity,
nextCountry,
nextCity;
for (var i = 0; i < (aTemp.length); i++) {
if (hasCity(aTemp[i])) {
currentCountry = countryRe.exec(aTemp[i])[1];
currentCity = cityRe.exec(aTemp[i])[1];
} else {
currentCountry = aTemp[i];
currentCity = false;
}
if (hasCity(aTemp[i + 1])) {
nextCountry = countryRe.exec(aTemp[i + 1])[1];
nextCity = cityRe.exec(aTemp[i + 1])[1];
} else {
nextCountry = aTemp[i + 1];
nextCity = false;
}
if (currentCountry === nextCountry && nextCity && currentCity) {
aTemp[i] = currentCountry + "(" + currentCity + "," + nextCity + ")";
aTemp.splice(i + 1, 1);
i = 0;
} else if (currentCountry === nextCountry && nextCity) {
aTemp[i] = currentCountry + "(" + nextCity + ")";
aTemp.splice(i + 1, 1);
i = 0;
} else if (currentCountry === nextCountry && currentCity) {
aTemp[i] = currentCountry + "(" + currentCity + ")";
aTemp.splice(i + 1, 1);
i = 0;
} else if (currentCountry === nextCountry) {
aTemp[i] = currentCountry;
aTemp.splice(i + 1, 1);
i = 0;
}
}
return aTemp;
};
var result = groupCities(arrayPlacesSorted);
console.log(result);

split a javascript object in to a key value array

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.

Transform a JSON file?

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

Categories