Javascript Sum values of a list using map/reduce - javascript

I am very new to java and I need to use map and reduce functions. I made a lot of search but couldn't find a solution. Here is my data:
var lehighCounty = {
name: "Lehigh County",
population: 372492,
};
var philiCounty = {
name: "Philadelphia County",
population: 1596865,
};
var franklinCounty = {
name: "Franklin County",
population: 155592,
};
var northamptonCounty = {
name: "Northampton County",
population: 311359,
};
var pennCounties = [
lehighCounty, philiCounty, franklinCounty, northamptonCounty
];
print(pennCounties);
Using the code below, I can extract the population values of each object.
var population = pennCounties.map(function(county) {
return county.population; });
print(population);
[372492,1596865,155592,311359]
My main aim is to sum of each value using the reduce . I intended to apply the code below but I couldn't achieve.
List<Integer> integers = Arrays.asList(population);
Integer sum = integers.stream()
.reduce(0, (a, b) -> a + b);

You can use Array#reduce like so:
let lehighCounty={name:"Lehigh County",population:372492},philiCounty={name:"Philadelphia County",population:1596865},franklinCounty={name:"Franklin County",population:155592},northamptonCounty={name:"Northampton County",population:311359},pennCounties=[lehighCounty,philiCounty,franklinCounty,northamptonCounty];
let sum = pennCounties.reduce((acc, curr) => acc + curr.population, 0);
console.log(sum);

Related

how to get only one value from array data and convert it into comma separted values. using javascript without template literals

i have array data in the format given below
const data= [
{
name: "productname",
id: "1356",
price: "0.00",
category: "Health",
position: "1",
list: "New Products",
stocklevel: "20",
brand: "Health"
},
{
name: "productname2",
id: "5263",
price: "0",
category: "Hair",
position: "2",
list: "New Products",
stocklevel: "",
brand: "Hair"
}]
from this data i want only product name of each product by difference of product1 , product2.
for example i want the data in format of string by comma separated values like given below:-
product1name: "productname",
product2name: "productname2",
...
i tried using map function but not able to take only one or two values from whole array data.
here is the code what i tried
var dataByComa = '';
var Values = data
.map(function (p, i) {
return Object.keys(data[i]).map(function (k) {
return "prod" +" " + ": " + JSON.stringify(data[i][k]);
});
}).map(function (v) {
return v.join(",\n"); });
var commaValues = Values.join(",\n");
return commaValues;
with this code i can able to convert array data into comma separated values but i want only productnames.
Note :- Without using template template literals.
Edit: I'm more clear on what the OP was looking for now - here is an answer that fulfills all the requirements
let commaValues = ""
for (let i = 0; i < data.length; i++) {
commaValues += ("product" + (i + 1) + "name: " + "\"" + data[i]["name"] + "\", ")
}
// result: 'product1name: "productname", product2name: "productname2", '
You can do that using reduce. It takes a function as first and an initial value as second parameter (here an empty object {}).
The variable "previous" keeps track of the current state of the (initially empty) new object while the function adds the name of every single Element from the "data" array to the object.
var result = data.reduce((previous, element) => {
previous[element.name] = element.name;
return previous;
}, {})
EDIT:
As i realized, you actually want a string as result. In that case you could do:
var result = data.reduce((previous, element) => {
previous[element.name] = element.name;
return previous;
}, {})
var csvWithBrackets = JSON.stringify(result)
var csv = csvWithBrackets.substring(1, csvWithBrackets.length-1)
However the answer from Pzutils seems more compact.
You can iterate through the data and assign the value to an external variable like this:
let finalData = {}
data.forEach((item, index) => {
finalData[`product${index+1}name`] = item.name
})

Converted an Object with keys from multiple array for sorting and now want them back as arrays as they are in sorted

var values =selectValues;
var names = selectNames;
var priorities = prioritizedHours;
var prefers = preferHrsArray;
var years = workedYearsArray;
var items = values.map((value, index) => {
return {
value: value,
name: names[index],
priority: priorities[index],
prefer: prefers[index],
year: years[index]
}
});
var arrayObject = JSON.stringify(items);
Logger.log('Object array: '+arrayObject);
In the above program, I am creating an object from the arrays such as names, priorities, and so on. Resulting Object is following after I have made a sorting of them:
[
{"value":1,"name":"Fiona","prefer":30,"year":6},
{"value":1,"name":"Martin","prefer":40,"year":7},
{"value":2,"name":"Adam","prefer":0,"year":20},
{"value":2,"name":"Steve","prefer":100,"year":5}
]
Now as sorting is done, I want the arrays back as they are in the Object.
I am trying to get arrays like:
value = [1,1,2,2],
name = ['Fiona', 'Martin','Adam', 'Steve'],
prefer = [30,40,0,100],
year = [6,7,20,5]
Thank you for helping me out.
You can use forEach for this case
const array = [
{"value":1,"name":"Fiona","prefer":30,"year":6},
{"value":1,"name":"Martin","prefer":40,"year":7},
{"value":2,"name":"Adam","prefer":0,"year":20},
{"value":2,"name":"Steve","prefer":100,"year":5}
]
const values = []
const names = []
const prefers = []
const years = []
array.forEach(rec => {
values.push(rec.value),
names.push(rec.name),
prefers.push(rec.prefer),
years.push(rec.year)
})
console.log(values)
console.log(names)
console.log(prefers)
console.log(years)
Map should work:
const data = [
{ value: 1, name: "Fiona", prefer: 30, year: 6 },
{ value: 1, name: "Martin", prefer: 40, year: 7 },
{ value: 2, name: "Adam", prefer: 0, year: 20 },
{ value: 2, name: "Steve", prefer: 100, year: 5 },
];
const values = data.map(x=>x.value);
const names = data.map(x=>x.name);
console.log(values, names);
//[ 1, 1, 2, 2 ] [ 'Fiona', 'Martin', 'Adam', 'Steve' ]
See MDN for details of map
You could also make it a little more dynamic by using reduce and then only getting the lists you want using Object destructuring.
const arr = [
{"value":1,"name":"Fiona","prefer":30,"year":6},
{"value":1,"name":"Martin","prefer":40,"year":7},
{"value":2,"name":"Adam","prefer":0,"year":20},
{"value":2,"name":"Steve","prefer":100,"year":5}
];
const {name, value, prefer, year} = arr.reduce((acc, curr) => {
Object.entries(curr).forEach(([key, val]) => {
if(acc[key] == null)
acc[key] = [];
acc[key].push(val);
});
return acc;
}, {})
console.log(name);
console.log(value);
console.log(prefer);
console.log(year);

Sum up JSON array items by common key

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

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;

convert array into an array of ojects

I have the following array list.
var data = [ "USA", "Denmark", "London"];
I need to convert it in this form
var data = [
{ "id" : 1, "label": "USA" },
{ "id" : 2, "label": "Denmark" },
{ "id" : 3, "label": "London" }
];
Can anyone please let me know how to achieve this.
Pretty easy using Array.map (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
var formatted = data.map(function(country, index) {
return { id: (index + 1), label: country }
});
Simple version:
var convertedData = []
for (var i in data){
convertedData.push({id: i+1, label: data[i]});
}
data = convertedData; //if you want to overwrite data variable
You can use forEach to loop through the data array
var data = [ "USA", "Denmark", "London"];
var demArray =[];
data.forEach(function(item,index){
demArray.push({
id:index+1,
label:item
})
})
console.log(demArray)
JSFIDDLE
Underscore way (for old browsers without Array.map support):
var res = _.map(data, function(p, i){
return {id: i + 1, label: p};
});

Categories