Sum of same object name in javascript - javascript

Hi friends I'm beginner for javascript how i sum same n no's of object name corresponding value and push the result to new array.see this is sample object
var obj_1 ={'delivered':10,'due':11,'team_name':'UK'};
var obj_2 ={'delivered':10,'due':11,'team_name':'US'};
var obj_nth ={'delivered':10,'due':11,'team_name':'UK'};
but i expect this output [UK:{'delivered':20,'due':22},US:{'delivered':10,'due':11}],so please help me what i'll do next

You can first create array of objects and then reduce() to return one object.
var obj_1 ={'delivered':10,'due':11,'team_name':'UK'};
var obj_2 ={'delivered':10,'due':11,'team_name':'US'};
var obj_nth ={'delivered':10,'due':11,'team_name':'UK'};
var result = [obj_1, obj_2, obj_nth].reduce(function(r, e) {
if(!r[e.team_name]) {
r[e.team_name] = {delivered:0,due:0}
}
r[e.team_name].delivered += e.delivered
r[e.team_name].due += e.due
return r
}, {})
console.log(result)

const newArray = initialArray.map(({team_name, ...restProps}) => {
return {
[team_name]: {...restProps}
};
});
See:
Arrow functions
Spread operator
Array.prototype.map
Computed property names

var obj_1 ={'delivered':10,'due':11,'team_name':'UK'};
var obj_2 ={'delivered':10,'due':11,'team_name':'US'};
var obj_nth ={'delivered':10,'due':11,'team_name':'UK'};
function sum_all() {
var sum={};
for(var i=0;i<arguments.length;i++) {
obj = arguments[i];
if (!sum[obj.team_name]) {
sum[obj.team_name]={'delivered':0,'due':0};
}
sum[obj.team_name].delivered += obj.delivered;
sum[obj.team_name].due += obj.due;
}
return sum;
}
var sum = sum_all(obj_1,obj_2,obj_nth);
console.log(sum);
Your console output will be:
sum
Object
UK: Object
delivered: 20
due: 22
US: Object
delivered: 10
due: 11

Store these objects in an array, such as:
var myObjects = [
{'delivered':10,'due':11,'team_name':'UK'},
{'delivered':10,'due':11,'team_name':'US'},
{'delivered':10,'due':11,'team_name':'UK'}
];
Create a new object in which you will store your results:
var results = {};
Then iterate through the array with a for loop (as it is generally faster) and add the other properties according to team_name:
for (var i = 0; i <= myObjects.length; i++) {
if (typeof results[myObjects[i].team_name] !== undefined) {
results[myObjects[i]].delivered += myObjects[i].delivered;
results[myObjects[i]].due += myObjects[i].due;
} else {
// Set 0 to these properties if the entry didn't exist
results[myObjects[i]].delivered = 0;
results[myObjects[i]].due = 0;
}
}

Related

How to restructure my JSON object

I implemented an aggregation function but the only problem I have now is that I lost my key: value format e.g [{name:"Apples",val:8},{name:"Banana",val: 9}].
function agrregate(a){
var targetObj = {};
var result;
var b = JSON.parse(JSON.stringify(a));
var trees= b.length;
if(!trees){
trees = 0
}
for (var i = 0; i < trees; i++) {
if (!targetObj.hasOwnProperty(b[i].key)) {
targetObj[b[i].key] = 0;
}
targetObj[b[i].key] += b[i].val;
}
result = JSON.stringify(targetObj);
return result;
}
This is the result i get when agrregate function completes.
{"Apple":8,"Banana":9}
Instead of
{name:"Apple", val:8}, {name:"Banana", val:9}
Use a reducer to aggregate. You don't need to do stuff with JSON stringify/parse.
To get back to an array of objects, you use map and Object.keys
var test = [{name:"Apples",val:5},{name:"Banana",val: 9},{name:"Apples",val:3}]
var aggregate = function(arr) {
return arr.reduce(function(result, obj) { // Create one object (result)
result[obj.name] = (result[obj.name] || 0) + obj.val; // Add a new key/or increase
return result // Return the object
}, {});
};
var wrap = function(obj) {
return Object.keys(obj) // Create an array of keys
.map(function(key) {
return { // Specify the format
name: key,
val: obj[key]
};
});
};
console.log(aggregate(test));
console.log(wrap(aggregate(test)));

Filter Array on same name and date

var Array = [{"Name":"Temp","Date":"2014-10-23"},
{"Name":"Temp","Date":"2014-10-22"},
{"Name":"Temp","Date":"2014-10-18"},
{"Name":"Temp","Date":"2014-10-19"},
{"Name":"Temp2","Date":"2014-10-12"},
{"Name":"Temp2","Date":"2014-06-12"}]
What would be the best way to filter the above array on the following condition.
*If the name is the same, then filter away all the objects with the same name and leave only the object with the latest date left.
All I can think of is to do for loops. Note that Date is a real dateObject and not a string as I have wrote above which means that you can do Date comparisons.
Using Array.reduce(), i was able to get it down to an object containing only Temp and Temp2 with their dates:
var obj = array.reduce(function(base,cur){
if (base[cur.Name]) {
if (base[cur.Name].Date < cur.Date) {
base[cur.Name].Date = cur.Date;
} else {
return base;
}
} else {
base[cur.Name] = cur;
return base;
}
},{});
From there, you can just get the object's values with Object.keys().map():
array = Object.keys(obj).map(function(k){
return obj[k];
});
var array = [{"Name":"Temp","Date":new Date("2014-10-23")},
{"Name":"Temp","Date":new Date("2014-10-22")},
{"Name":"Temp","Date":new Date("2014-10-18")},
{"Name":"Temp","Date":new Date("2014-10-19")},
{"Name":"Temp2","Date":new Date("2014-10-12")},
{"Name":"Temp2","Date":new Date("2014-06-12")}];
var obj = {};
for(var i in array){
if(!obj[array[i].Name] || obj[array[i].Name].getTime() < array[i].Date.getTime())
obj[array[i].Name] = array[i].Date;
}
then if you need it to be an array of objects:
array = [];
for(var name in obj){
array.push({Name: name, Date: obj[name]});
}
var Array = [{"Name":"Temp","Date":"2014-10-23"},
{"Name":"Temp","Date":"2014-10-22"},
{"Name":"Temp","Date":"2014-10-18"},
{"Name":"Temp","Date":"2014-10-19"},
{"Name":"Temp2","Date":"2014-10-12"},
{"Name":"Temp2","Date":"2014-06-12"}]
var result = {};
Array.forEach(function(item) {
var name = item['Name'];
if(result[name]) {
result[name].push(item['Date']);
} else {
result[name] = [item['Date']];
}
})
Object.keys(result).forEach(function(item) {
result[item] = Math.max.apply(null, result[item]);
})
aggragate the array by name to {Name: 'Temp', Date: ['2014-10-23', '2013-10-32', 'xxxx']}
then get the max date by Math.max.apply
Here you go, Works perfect for any random orders
var Array = [{"Name":"Temp","Date":"2014-10-03"},
{"Name":"Temp","Date":"2014-10-22"},
{"Name":"Temp","Date":"2014-10-18"},
{"Name":"Temp","Date":"2014-10-19"},
{"Name":"Temp2","Date":"2014-10-12"},
{"Name":"Temp2","Date":"2014-06-12"}];
var tempArray = []; //This array will hold your Result Set
var tempArrayName = [];
var tempDate = {};
$.each(Array, function(i, v) {
if(tempArrayName.indexOf(Array[i].Name) < 0){
tempArray.push({ "Name":Array[i].Name,"Date":Array[i].Date});
tempArrayName.push(Array[i].Name);
tempDate[Array[i].Name] = Array[i].Date;
}else{
if( new Date((Array[i].Date))> new Date(tempDate[Array[i].Name])){
$.each(tempArray, function(j, k) {
if(tempArray[j].Name == Array[i].Name){
tempArray[j].Date = Array[i].Date;
}
});
}
}
});
console.log(tempArray);
I'd advise against overwriting the Array object. Anyhow,
one way would be to group the dates using an object:
var data = [
{"Name":"Temp","Date": new Date("2014-10-23")},
{"Name":"Temp","Date": new Date("2014-10-22")},
{"Name":"Temp","Date": new Date("2014-10-18")},
{"Name":"Temp","Date": new Date("2014-10-19")},
{"Name":"Temp2","Date": new Date("2014-10-12")},
{"Name":"Temp2","Date": new Date("2014-06-12")}
];
var name2dates = Object.create(null);
data.forEach(function(thing){
if(!name2dates[thing.Name]){
name2dates[thing.Name] = thing.Date;
}else{
name2dates[thing.Name] = thing.Date > name2dates[thing.Name] ?
thing.Date : name2dates[thing.Name];
}
});
And to create a 'filtered' array from this, if that's what you
need, then:
Object.keys(name2dates).map(function(name){
return {Name: name, Date: name2dates[name]};
});
Is this helpful?
$.grep(Array, function(v) {
return v.Name === "Temp";
}).reduce(function (a, b) { return a.Date > b.Date ? a : b; });

Converting js array into dictionary map

I have this array:
["userconfig", "general", "name"]
and I would like it to look like this
data_structure["userconfig"]["general"]["name"]
I have tried this function:
inputID = "userconfig-general-name"
function GetDataByID(inputID){
var position = '';
for (var i = 0; i < inputID.length; i++) {
var hirarchy = inputID[i].split('-');
for (var index = 0; index < hirarchy.length; index++) {
position += '["'+ hirarchy[index] +'"]';
}
}
return data_structure[position];
}
while hirarchy is the array. I get the [position] as a string which is not working well.
how can I make a js function which builds the object path dynamically by an array?
var arr = ["userconfig", "general", "name"];
var dataStructure = arr.reduceRight(function (value, key) {
var obj = {};
obj[key] = value;
return obj;
}, 'myVal');
Ends up as:
{ userconfig : { general : { name : 'myVal' } } }
Note that you may need a polyfill for the reduceRight method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight
The below function will take an object to modify and an array filled with the properties needed:
function objPath(obj,path){
path.forEach(function(item){
obj[item] = {};
obj = obj[item];
});
}
var myobj = {};
objPath(myobj,["test","test2","test3"]);
console.log(myobj);
//outputs
Object {test: Object}
test: Object
test2: Object
test3: Object
The function loops over the array creating the new object property as a new object. It then puts a reference to the new object into obj so that the next property on the new object can be made.
JSFiddle
Recursive function
var array = ["userconfig", "general", "name"];
function toAssociative(array) {
var index = array.shift();
var next = null;
if (array.length > 0) {
next = toAssociative(array);
}
var result = new Array();
result[index] = next;
return result;
}

Combining results into one object

I'm looping through a set of inputs. I need to tally up the grouped totals. The inputs below to one of three categories.
How do I go about combining the values up relevant to three categories?
var compoundedArray = new Array();
holder.find(".dataset input").each(function(index) {
var val = $(this).val();
var dataType = $(this).data("type");
var localObj = {};
localObj[dataType] = val;
compoundedArray.push(localObj);
});
I have an object like this
[
{
"growth":30
},
{
"growth": 40
},
{
"other": 20
}
]
how do I loop through the object to produce something like
[
{
"growth": 70
},
{
"other": 20
}
]
if I looped over the initial array object
for (var i = 0; i < compoundedArray.length; i++) {
console.log(compoundedArray[i]);
}
how would I go about checking to ensure I don't have duplicates - and that I can tally up the results?
Ideally the resulting format may be the best
var array = [
"matching": 50,
"growth": 20
]
var array = [
"matching": 50,
"growth": 20
]
is not valid JS, but you can create an object of the form
var obj = {
"matching": 50,
"growth": 20
};
And that's pretty easy to do, just use an object from the very beginning:
var result = {};
holder.find(".dataset input").each(function(index) {
var val = +$(this).val(); // use unary plus to convert to number
var dataType = $(this).data("type");
result[dataType] = (result[dataType] || 0) + val;
});
Further reading material:
MDN - Working with Objects
Eloquent JavaScript - Data structures: Objects and Arrays
You can just use an object (not array) with unique keys.
var compoundedObj = {};
$(".dataset input", holder).each(function() {
var dataType = $(this).data("type");
if(!compoundedObj.hasOwnProperty(dataType)) {
compoundedObj[dataType] = 0;
}
compoundedObj[dataType] += parseInt($(this).val(), 10);
});
In this way you'll get an object like this:
{
"growth": 70,
"other": 20
}
Live demo
http://jsfiddle.net/GFwGU/
var original = [{"growth":30},{"growth": 40},{"other": 20}]
// object to sum all parts by key
var sums = {}
// loop through original object
for(var index in original){
// get reference to array value (target object)
var outer = original[index]
// loop through keys of target object
for(var key in outer){
// get a reference to the value
var value = outer[key]
// set or add to the value on the sums object
sums[key] = sums[key] ? sums[key] + value : value
}
}
// create the output array
var updated = []
// loop through all the summed keys
for(var key in sums){
// get reference to value
var value = sums[key]
// create empty object
var dummy = {}
// build object into desired format
dummy[key] = value
// push to output array
updated.push(dummy)
}
// check the results
alert(JSON.stringify( updated ))
var add=function (a,b){ a=a||0; b=b||0; return a+b};
var input=[ {growth:30},{growth:40},{other:20} ],output=[],temp={};
$.each(input,function(i,o){
var n;
for(i in o)
{n=i;break}
temp[n]=add(temp[n],o[n]);
});
$.each(temp,function(i,o){
var k={};
k[i]=o;
output.push(k)
});

How to convert an array of objects into a mapped object in JavaScript?

How can I convert something like initialArray array of JSON objects into finalObject map?
var initialArray = [
{ id:'id1', name:'name1' },
{ id:'id2', name:'name2' },
{ id:'id3', name:'name3' },
{ id:'id4', name:'name4' }
];
var finalObject = {
'id1':'name1',
'id2':'name2',
'id3':'name3',
'id4':'name4'
}
Things to consider:
IDs are strings.
I tried for in loop - couldn't make it to work - http://jsfiddle.net/5af9R/23/
Any ideas?
You need to operate on the objects in your array, not strings containing their indexes in the array.
You should also use a regular for loop to iterate over an array.
Your JSFiddle, fixed:
var x = [ {id:'1', img:'img1'}, {id:'2', img:'img2'}, {id:'3', img:'img3'} ];
var resp = {};
for( var i = 0 ; i < x.length ; i++ ){
var obj = x[i];
resp[obj.id] = obj.img;
}
document.write( JSON.stringify(resp, undefined, 2) );
​
DEMO
You can loop over the array, and for each object, add a new property to finalObject whose property name is the id, and whose value is the name.
var finalObject = {};
for (var i = 0, max = initialArray.length; i < max; i++)
finalObject[initialArray[i].id] = initialArray[i].name;
resp[key.id] = key.img;
You correctly call it key. But you need a value;
resp[x[key].id] = x[key].img;
var finalObject = initialArray.reduce(function(ret, obj){
ret[obj.id] = obj.name;
return ret;
}, {});
This solution is specific to the property names for the specific question, but Array.prototype.reduce is a function I use all the time for any sort of array iteration that requires a non-array result.
You're not using For In correctly jsFiddle
var x = [ {id:'1', img:'img1'}, {id:'2', img:'img2'}, {id:'3', img:'img3'} ];
var resp = {};
for( var key in x ){
resp['id' + x[key].id] = x[key].img;
}
document.write( JSON.stringify(resp, undefined, 2) );
​
for (var i=0; i<x.length; i++) {
var id = 'id' + x[i].id;
var img = x[i].img;
resp[id] = img;
}
if i have understood correctly you can do something like
var x =' [ {"id":"1", "img":"img1"}, {"id":"2", "img":"img2"}, {"id":"3", "img":"img3"}]';
var resp = {};
var json = $.parseJSON(x);
$(json).each(function(i,v){
resp[v.id]=v.img;
});
console.log( resp);
DEMO
you talked about json but in the fiddle you provided there was no json even jquery was not added as a resource so i made some assumptions
Today I was on the same question and I didn't find an answer here, except the answer of #adam-rackis.
The way I found is :
var initialArray = [
{ id:'id1', name:'name1' },
{ id:'id2', name:'name2' },
{ id:'id3', name:'name3' },
{ id:'id4', name:'name4' }
],
finalObject = {};
$.each(initialArray, function(k,v) {
finalObject[v.name] = v.value;
});

Categories