Sum up JSON array items by common key - javascript

Im facing a tricky problem in forming a JSON array.
I have a below JSON where products are duplicated,
var mainJson = [{
"product": "pen",
"quantity": 3
}, {
"product": "pen",
"quantity": 3
}, {
"product": "pencil",
"quantity": 4
}, {
"product": "pencil",
"quantity": 4
}]
now i want to remove the duplicated and i want to add Quantity field and my final output should look like below...
var finalOutput = [{
"product":"pen",
"quantity":6
},{
"product":"pencil",
"quantity":8
}]
Im able to remove the duplicate records with same product name but im not able to concatenate the quantity field at the time of elimination..
Can someone please help me to resolve this?
Thank you in advance

You may walk through your source array, using Array.prototype.reduce() and insert into resulting array item, having product value found for the first time, or add current quantity should one already exist:
const mainJson = [{"product":"pen","quantity":3},{"product":"pen","quantity":3},{"product":"pencil","quantity":4},{"product":"pencil","quantity":4}],
groupped = mainJson.reduce((res,{product,quantity}) => {
const group = res.find(item => item.product == product)
group ?
group.quantity += quantity :
res.push({product,quantity})
return res
}, [])
console.log(groupped)
.as-console-wrapper {min-height: 100%}
EDIT:
Above algorithm (having O(n²) time complexity) will perform nicely when the number of unique product items is relatively small, however for large number of product items, it is reasonable (just like #CameronDowner and #StepUp suggest) to build up a sort of hash map (first pass) with products and respective totals and transform that into array of desired format (second pass) which makes it O(n) time complexity:
const mainJson = [{"product":"pen","quantity":3},{"product":"pen","quantity":3},{"product":"pencil","quantity":4},{"product":"pencil","quantity":4}],
groupObj = mainJson.reduce((r,{product,quantity}) =>
(r[product] = (r[product]||0) + quantity, r), {}),
group = Object.keys(groupObj).map(key => ({product:key, quantity: groupObj[key]}))
console.log(group)
.as-console-wrapper {min-height: 100%}

I would do this in two stages. First I would reduce the array into an object, with the product as the key and the quantity as the value.
This handles the duplicates very well because object keys can never be duplicated.
I would then map this, using Object.entries, back to an array in the desired format. Using array destructuring can make this step very clean.
const mainJson = [
{
product: "pen",
quantity: 3
},
{
product: "pen",
quantity: 3
},
{
product: "pencil",
quantity: 4
},
{
product: "pencil",
quantity: 4
}
];
const productQuantities = mainJson.reduce((acc, curr) => {
const { product, quantity } = curr;
const currentValue = acc[product] || 0; // default to zero if not set yet
return {
...acc,
[product]: currentValue + quantity
};
}, {});
console.log(productQuantities);
const productQuantitiesArray = Object.entries(
productQuantities
).map(([product, quantity]) => ({ product, quantity }));
console.log(productQuantitiesArray);

While the reduce method is quite Javascript, if you prefer a more generic way, you can do it in two steps:
Iterate over your JSON and create a Map with no duplicated items;
Iterate over the Map and get your final JSON.
Take in mind this solution is the hard way, and it is slower than the reduce method. I will not blame you if you keep with the nicer reduce option, I just wanted to point out this more generic way! The result is the same.
Following the steps, we have:
var mainJson = [{"product": "pen","quantity": 3}, {"product": "pen","quantity": 3},
{"product": "pencil","quantity": 4}, {"product": "pencil","quantity": 4}];
// Step 1
var mapJson = new Map();
for(let item of mainJson)
{
if (mapJson.has(item.product))
mapJson.set(item.product, mapJson.get(item.product) + item.quantity);
else
mapJson.set(item.product, item.quantity);
}
// Step 2
var finalJson = [];
for(let item of mapJson)
finalJson.push({product:item[0], quantity:item[1]});
console.log(finalJson);

We can use reduce function:
const result = mainJson.reduce( (a, {product, quantity})=> {
a[product] = a[product] || {product, quantity: 0};
a[product].quantity += quantity;
return a;
},{})
An example:
var mainJson = [{
"product": "pen",
"quantity": 3
}, {
"product": "pen",
"quantity": 3
}, {
"product": "pencil",
"quantity": 4
}, {
"product": "pencil",
"quantity": 4
}];
const result = mainJson.reduce( (a, {product, quantity})=> {
a[product] = a[product] || {product, quantity: 0};
a[product].quantity += quantity;
return a;
},{})
console.log(Object.values(result));
If you are bothering about performance, then you can use the following solution.
const result = mainJson.reduce( (a, {product, quantity})=> {
a[product] = a[product] || {product, quantity: 0};
a[product].quantity += quantity;
return a;
},{})
let vals = [];
for (var key in result) {
if (result.hasOwnProperty(key) ) {
vals.push(result[key]);
}
}
console.log(vals);
You can see results at JSBench.me

Related

Move an element to the front of an array: Javascript [duplicate]

This question already has answers here:
Move an array element from one array position to another
(44 answers)
Closed 2 years ago.
I have an array of objects with this format
let arr = [ { name: "test1", id: 5}, { name: "test2", id: 6 } , { name: "test3", id: 8 } ]
Now I basically want to move the item with 6 to the front of the array by re-arranging so that result becomes
let result = [ { name: "test2", id: 6 } , { name: "test1", id: 5}, { name: "test3", id: 8 } ]
What I have tried
const found = arr.find((element) => {
return element.id === 6;
});
if (found) {
const [...arr, found] = arr;
return found;
} else {
return arr;
}
You can make use of Array.unshift and Array.splice.
let arr = [{name:"test1",id:5},{name:"test2",id:6},{name:"test3",id:8}]
const moveToFront = (data, matchingId) => {
//find the index of the element in the array
const index = data.findIndex(({id}) => id === matchingId);
if(index !== -1) {
//if the matching element is found,
const updatedData = [...data];
//then remove that element and use `unshift`
updatedData.unshift(...updatedData.splice(index, 1));
return updatedData;
}
//if the matching element is not found, then return the same array
return data;
}
console.log(moveToFront(arr, 6));
.as-console-wrapper {
max-height: 100% !important;
}
You could sort the array with the delta of the checks.
const
array = [{ name: "test1", id: 5 }, { name: "test2", id: 6 }, { name: "test3", id: 8 }];
array.sort((a, b) => (b.id === 6) - (a.id === 6));
console.log(array);
const array = [{ name: "test1", id: 5 }, { name: "test2", id: 6 }, { name: "test3", id: 8 }];
const sortedArray = array.sort((a, b) => (b.id === 6) - (a.id === 6)); console.log(sortedArray);
discusses an easy way to sort your JavaScript Array by the order of the index number for each item in the Array object. This can be helpful if you want to sort alphabetically and not need to create a new String Array with a function like String.sort().
A quick tip that can be useful to you if you want a quick solution to sorting an Array in JavaScript is below.Remember that it is always best practice to use the Array methods built into the language. They are created to work fast and efficient. However, if you really want to sort your array by index number and not have an array of strings, then this article will be for you.:
String→Number: When a function returns a Number value, then JavaScript interprets it as being equal to the Number value in the code...The function is used by passing two parameters, which should return true when they are equal and false when they are not equal.In this case, we are sort of reverse comparing them. We are checking the ID of the items inside the Array to see if they match, but we subtract one to check if they are less than. This is because when we call .sort(), JavaScript is sorting alphabetically and an ID with a value of 6 will be at the end of the list. So, a value of -1 will make it appear in the correct order.If you want to use this method for your Array, then please add a comment below!
You can use Array.unshift() to add element to the beginning of the array and Array.splice() to remove the array element.
let arr = [ { name: "test1", id: 5}, { name: "test2", id: 6 } , { name: "test3", id: 8 } ]
let result = [...arr];
const index = result.findIndex(e => e.id === 6)
result.unshift(result.splice(index, 1)[0])
console.log(result);
You can make use of filter and unshift
let arr = [{ name: "test1", id: 5 },{ name: "test2", id: 6 },{ name: "test3", id: 8 }];
let firstObject;
let result = arr.filter((value) => {
if (value.id != 6) return value;
firstObject = value;
});
result.unshift(firstObject);
console.log(result);

Sort array of objects by given incomplete array of orders in Javascript

I have an array of objects:
var items = [
{
"id":"sugar",
"type": 'eatables'
},
{
"id":"petrol",
"type": 'utility'
},
{
"id":"apple",
"type": 'fruits'
},
{
"id":"mango",
"type": 'fruits'
},
{
"id":"book",
"type": 'education'
}
];
Now I have another array of orders with the help of which I want to sort items array:
var orders = [
{
"id":"sugar",
"order":5
},
{
"id":"book",
"order":1
}
];
Now what I am trying so far in my logic is that I am putting so many loops that it is totally creating mess.
Can anyone suggest me with a short and optimized logic for this?
One approach could be creating one dictionary which will keep the order for every element. Also, I've iterated the whole items array to store the position for the elements that are not in the orders array.
First of all, I'll declare one array which keep the whole orders, thus one array with 1..N elements.
var orderNumbers = Array.from({length: items.length}, (_, v) => v + 1);
Then I started to create the dictionary by iterating orders array and remove orders from orderNumbers.
The last step is iterating the items array and use shift method to "pop" the first element.
The final dictionary will look like
{
"sugar": 2,
"book": 3,
"petrol": 1,
"apple": 4,
"mango": 5
}
In this code I used one dictionary because its lookup has complexity of O(1).
var items = [ { "id":"sugar", "type": 'eatables' }, { "id":"petrol", "type": 'utility' }, { "id":"apple", "type": 'fruits' }, { "id":"mango", "type": 'fruits' }, { "id":"book", "type": 'education' } ], orders = [ { "id":"sugar", "order":2 }, { "id":"book", "order":3 } ], orderNumbers = Array.from({length: items.length}, (_, v) => v + 1);
var ordersDict = orders.reduce((acc, item) => {
acc[item.id] = item.order;
//remove from order numbers
let index = orderNumbers.findIndex(el => el == item.order);
orderNumbers.splice(index, 1);
return acc;
}, {});
for(let i = 0; i < items.length; i++){
if(!ordersDict.hasOwnProperty(items[i].id)){
ordersDict[items[i].id] = orderNumbers[0];
orderNumbers.shift();
}
}
//sort the array
items.sort((a,b) => ordersDict[a.id] - ordersDict[b.id]);
console.log(items);
let oorder = new Object();
orders.map(item=>{oorder[item.id]=item.order});
var new_items = [];
items.map(item=>{new_items[oorder[item.id]-1]=item});

Efficient mapping of arrays

I am trying to find out the best / most efficient or most functional way to compare / merge / manipulate two arrays (lists) simultaneously in JS.
The example I give below is a simple example of the overall concept. In my current project, I deal with some very crazy list mapping, filtering, etc. with very large lists of objects.
As delinated below, my first idea (version1) on comparing lists would be to run through the first list (i.e. map), and in the anonymous/callback function, filter the second list to meet the criteria needed for the compare (match ids for example). This obviously works, as per version1 below.
I had a question performance-wise, as by this method on every iteration/call of map, the entire 2nd list gets filtered just to find that one item that matches the filter.
Also, the filter passes every other item in list2 which should be matched in list1. Meaning (as that sentence probably did not make sense):
list1.map list2.filter
id:1 [id:3,id:2,id:1]
^-match
id:2 [id:3,id:2,id:1]
^-match
id:3 [id:3,id:2,id:1]
^-match
Ideally on the first iteration of map (list1 id:1), when the filter encounters list2 id:3 (first item) it would just match it to list1 id:3
Thinking with the above concept (matching to a later id when it is encountered earlier, I came up with version2).
This makes list2 into a dictionary, and then looks up the value in any sequence by key.
const list1 = [
{id: '1',init:'init1'},
{id: '2',init:'init2'},
{id: '3',init:'init3'}
];
const list2 = [
{id: '2',data:'data2'},
{id: '3',data:'data3'},
{id: '4',data:'data4'}
];
/* ---------
* version 1
*/
const mergedV1 = list1.map(n => (
{...n,...list2.filter(f => f.id===n.id)[0]}
));
/* [
{"id": "1", "init": "init1"},
{"id": "2", "init": "init2", "data": "data2"},
{"id": "3", "init": "init3", "data": "data3"}
] */
/* ---------
* version 2
*/
const dictList2 = list2.reduce((dict,item) => (dict[item.id]=item,dict),{});
// does not handle duplicate ids but I think that's
// outside the context of this question.
const mergedV2 = list1.map(n => ({...n,...dictList2[n.id]}));
/* [
{"id": "1", "init": "init1"},
{"id": "2", "init": "init2", "data": "data2"},
{"id": "3", "init": "init3", "data": "data3"}
] */
JSON.stringify(mergedV1) === JSON.stringify(mergedV2);
// true
// and just for fun
const sqlLeftOuterJoinInJS = list1 => list2 => on => {
const dict = list2.reduce((dict,item) => (
dict[item[on]]=item,dict
),{});
return list1.map(n => ({...n,...dict[n[on]]}
))};
Obviously the above examples are pretty simple (merging two lists, each list having a length of 3). There are more complex instances that I am working with.
I don't know if there are some smarter (and ideally functional) techniques out there that I should be using.
You could take a closure over the wanted key for the group and a Map for collecting all objects.
function merge(key) {
var map = new Map;
return function (r, a) {
a.forEach(o => {
if (!map.has(o[key])) r.push(map.set(o[key], {}).get(o[key]));
Object.assign(map.get(o[key]), o);
});
return r;
};
}
const
list1 = [{ id: '1', init: 'init1' }, { id: '2', init: 'init2' }, { id: '3', init: 'init3' }],
list2 = [{ id: '2', data: 'data2' }, { id: '3', data: 'data3' }, { id: '4', data: 'data4' }],
result = [list1, list2].reduce(merge('id'), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using filter for search is a misstep. Your instinct in version 2 is much better. Map and Set provide much faster lookup times.
Here's a decomposed approach. It should be pretty fast, but maybe not as fast as Nina's. She is a speed demon >_<
const merge = (...lists) =>
Array .from
( lists
.reduce (merge1, new Map)
.values ()
)
const merge1 = (cache, list) =>
list .reduce
( (cache, l) =>
cache .has (l.id)
? update (cache, l.id, l)
: insert (cache, l.id, l)
, cache
)
const insert = (cache, key, value) =>
cache .set (key, value)
const update = (cache, key, value) =>
cache .set
( key
, { ...cache .get (key)
, ...value
}
)
const list1 =
[{ id: '1', init: 'init1' }, { id: '2', init: 'init2' }, { id: '3', init: 'init3' }]
const list2 =
[{ id: '2', data: 'data2' }, { id: '3', data: 'data3' }, { id: '4', data: 'data4' }]
console .log (merge (list1, list2))
I'm offering this for completeness as I think Nina and #user633183 have offered most likely more efficient solutions.
If you wish to stick to your initial filter example, which is a max lookup N*M, and your arrays are mutable; you could consider reducing the set as you traverse through. In the old days shrinking the array had a huge impact on performance.
The general pattern today is to use a Map (or dict) as indicated in other answers, as it is both easy to understand and generally efficient.
Find and Resize
const list1 = [
{id: '1',init:'init1'},
{id: '2',init:'init2'},
{id: '3',init:'init3'}
];
const list2 = [
{id: '2',data:'data2'},
{id: '3',data:'data3'},
{id: '4',data:'data4'}
];
// combine by ID
let merged = list1.reduce((acc, obj)=>{
acc.push(obj);
// find index by ID
let foundIdx = list2.findIndex( el => el.id==obj.id );
// if found, store and remove from search
if ( foundIdx >= 0 ){
obj.data = list2[foundIdx].data;
list2.splice( foundIdx, 1 ); // shrink lookup array
}
return acc;
},[]);
// store remaining (if you want); i.e. {id:4,data:'data4'}
merged = merged.concat(list2)
console.log(merged);
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}
I'm not sure whether I should mark this question as a duplicate because you phrased it differently. Anyway, here's my answer to that question copied verbatim. What you want is an equijoin:
const equijoin = (xs, ys, primary, foreign, sel) => {
const ix = xs.reduce((ix, row) => // loop through m items
ix.set(row[primary], row), // populate index for primary table
new Map); // create an index for primary table
return ys.map(row => // loop through n items
sel(ix.get(row[foreign]), // get corresponding row from primary
row)); // select only the columns you need
};
You can use it as follows:
const equijoin = (xs, ys, primary, foreign, sel) => {
const ix = xs.reduce((ix, row) => ix.set(row[primary], row), new Map);
return ys.map(row => sel(ix.get(row[foreign]), row));
};
const list1 = [
{ id: "1", init: "init1" },
{ id: "2", init: "init2" },
{ id: "3", init: "init3" }
];
const list2 = [
{ id: "2", data: "data2" },
{ id: "3", data: "data3" },
{ id: "4", data: "data4" }
];
const result = equijoin(list2, list1, "id", "id",
(row2, row1) => ({ ...row1, ...row2 }));
console.log(result);
It takes O(m + n) time to compute the answer using equijoin. However, if you already have an index then it'll only take O(n) time. Hence, if you plan to do multiple equijoins using the same tables then it might be worthwhile to abstract out the index.

Finding percentages out of multiple in array and returning whole object by chance

I currently trying to make a lucky dip selector for prizes, I have an object that I would like to somehow transform into percentages which all depend on one another. I looked at other solutions online and have trouble doing so where I am looking inside an array and returning the whole object inside by chance
The max percentage in example will be 100%, and each qty would work out to the correct percentage that qty: 22 has the most likely chance of being picked and qty: 1 being the rarest and so on
{ tshirts: [
{ "tshirtName":"Green Shirt", "qty": 1, },
{ "tshirtName":"Blue Shirt", "qty": 2, },
{ "tshirtName":"Red Shirt", "qty": 7, },
{ "tshirtName":"Yellow Shirt", "qty": 22, },
]}
At the moment I made the mistake of just doing the following:
const randomChoice = Math.floor(Math.random() * prizes.tshirts.length);
console.log('Your prize is ' + prizes.tshirts[randomChoice].tshirtName);
But this does not take into account the different percentages needed for each qty, it makes it all a 25% chance each
Any help would be very appreciated, thank you
Find a random number between 1 and total quantity sum and get an element based on that.
let prizes = {"tshirts":[{"tshirtName":"Green Shirt","qty":1},{"tshirtName":"Blue Shirt","qty":2},{"tshirtName":"Red Shirt","qty":7},{"tshirtName":"Yellow Shirt","qty":22}]};
// variable for total quantity sum
let total = 0;
// create an array to keep reference of maximum value of random num
let range = prizes.tshirts.reduce((arr, { qty }, i) => {
arr[i] = (total += qty);
return arr;
}, [])
for (let i = 0; i < 100; i++) {
// get a random number between 1 to total
const randomChoice = Math.floor(Math.random() * total) + 1;
// get index based on the range array values
const index = range.findIndex(v => v >= randomChoice)
console.log('Your prize is ' + prizes.tshirts[index].tshirtName, randomChoice);
}
You can use an array and store a particular tshirts name as often as it's quantity.
Let me illustrate by a simple example. Imagine you have an array of numbers that looks a little like this:
var arr=[1,1,1,2];
If you now pick a random element out of this array using:
var element=arr[Math.floor(Math.random() * arr.length)];
there will be a high chance that the chosen element will be a 1 simply because there are 3 times as much 1s than 2s.
The same principle can be applied to your use case though we use the shirt names instead of numbers.
var prizes = {
tshirts: [{
"tshirtName": "Green Shirt",
"qty": 1,
},
{
"tshirtName": "Blue Shirt",
"qty": 2,
},
{
"tshirtName": "Red Shirt",
"qty": 7,
},
{
"tshirtName": "Yellow Shirt",
"qty": 22,
},
]
};
var tempArray = [];
prizes.tshirts.forEach(shirt => {
for (var a = 0; a < shirt.qty; a++) {
tempArray.push(shirt.tshirtName)
}
});
var element = tempArray[Math.floor(Math.random() * tempArray.length)];
console.log(element);
How about this?
let prizes = {
tshirts: [
{'tshirtName': 'Green Shirt', 'qty': 1},
{'tshirtName': 'Blue Shirt', 'qty': 2},
{'tshirtName': 'Red Shirt', 'qty': 7},
{'tshirtName': 'Yellow Shirt', 'qty': 22}
]
};
// total count of shirts
let count = prizes.tshirts.reduce((a, b) => a + b.qty, 0);
// Create an array containing each shirt instance qty times
let extendedArray = prizes.tshirts
.map(shirt => new Array(shirt.qty).fill(shirt)) // [[shirt1, shirt1], [shirt2, shitr2]]
.flat(); // [shirt1, shirt1, shirt2, shirt2]
console.log(getRandomShirt());
/**
* Simple integer random function
*/
function random(max, min) {
return Math.round(Math.random() * max) + min;
}
/**
* Call this for getting a shirt.
* Note, that the returned shirt is still the same instance like in prizes.tshirts
*/
function getRandomShirt() {
let randomValue = random(count, 0);
return extendedArray[randomValue];
}
const prizes = { tshirts: [
{ "tshirtName":"Green Shirt", "qty": 1,},
{ "tshirtName":"Blue Shirt", "qty": 2, },
{ "tshirtName":"Red Shirt", "qty": 7, },
{ "tshirtName":"Yellow Shirt", "qty": 22, }
]};
let Data = [];
prizes.tshirts.map(tshirt => {
let i = 0;
while( i < tshirt.qty){
Data.push(tshirt.tshirtName); i++; };
});
let randomChoice = Math.floor(Math.random()*Data.length);
console.log(Data[randomChoice]);

retriving values from javascript object and then convert it to one object

I have a problem! I am creating an rating app, and I have come across a problem that I don't know how to solve. The app is react native based so I am using JavaScript.
The problem is that I have multiple objects that are almost the same, I want to take out the average value from the values of the "same" objects and create a new one with the average value as the new value of the newly created object
This array in my code comes as a parameter to a function
var arr = [
{"name":"foo","value":2},
{"name":"foo","value":5},
{"name":"foo","value":2},
{"name":"bar","value":2},
{"name":"bar","value":1}
]
and the result I want is
var newArr = [
{"name":"foo","value":3},
{"name":"bar","value":1.5},
]
If anyone can help me I would appreciate that so much!
this is not my exact code of course so that others can take help from this as well, if you want my code to help me I can send it if that's needed
If you have any questions I'm more than happy to answer those
Iterate the array with Array.reduce(), and collect to object using the name values as the key. Sum the Value attribute of each name to total, and increment count.
Convert the object back to array using Object.values(). Iterate the new array with Array.map(), and get the average value by dividing the total by count:
const arr = [{"name":"foo","Value":2},{"name":"foo","Value":5},{"name":"foo","Value":2},{"name":"bar","Value":2},{"name":"bar","Value":1}];
const result = Object.values(arr.reduce((r, { name, Value }) => {
if(!r[name]) r[name] = { name, total: 0, count: 0 };
r[name].total += Value;
r[name].count += 1;
return r;
}, Object.create(null)))
.map(({ name, total, count }) => ({
name,
value: total / count
}));
console.log(result);
I guess you need something like this :
let arr = [
{name: "foo", Value: 2},
{name: "foo", Value: 5},
{name: "foo", Value: 2},
{name: "bar", Value: 2},
{name: "bar", Value: 1}
];
let tempArr = [];
arr.map((e, i) => {
tempArr[e.name] = tempArr[e.name] || [];
tempArr[e.name].push(e.Value);
});
var newArr = [];
$.each(Object.keys(tempArr), (i, e) => {
let sum = tempArr[e].reduce((pv, cv) => pv+cv, 0);
newArr.push({name: e, value: sum/tempArr[e].length});
});
console.log(newArr);
Good luck !
If you have the option of using underscore.js, the problem becomes simple:
group the objects in arr by name
for each group calculate the average of items by reducing to the sum of their values and dividing by group length
map each group to a single object containing the name and the average
var arr = [
obj = {
name: "foo",
Value: 2
},
obj = {
name: "foo",
Value: 5
},
obj = {
name: "foo",
Value: 2
},
obj = {
name: "bar",
Value: 2
},
obj = {
name: "bar",
Value: 1
}
]
// chain the sequence of operations
var result = _.chain(arr)
// group the array by name
.groupBy('name')
// process each group
.map(function(group, name) {
// calculate the average of items in the group
var avg = (group.length > 0) ? _.reduce(group, function(sum, item) { return sum + item.Value }, 0) / group.length : 0;
return {
name: name,
value: avg
}
})
.value();
console.log(result);
<script src="http://underscorejs.org/underscore-min.js"></script>
In arr you have the property Value and in newArr you have the property value, so I‘ll assume it to be value both. Please change if wished otherwise.
var map = {};
for(i = 0; i < arr.length; i++)
{
if(typeof map[arr[i].name] == ‘undefined‘)
{
map[arr[i].name] = {
name: arr[i].name,
value: arr[i].value,
count: 1,
};
} else {
map[arr[i].name].value += arr[i].value;
map[arr[i].name].count++;
}
var newArr = [];
for(prop in map)
{
map[prop].value /= map[prop].count;
newArr.push({
name: prop,
value: map[prop].value
});
}
delete map;

Categories