Return all values as an array after the map function - javascript

I want to write to the array the value of each sum of all the reports.
month: donate_report.report[0].reports[0].sum
Unfortunately, this function returns an empty array:
month: donate_report.report[0].reports;
const doubles = month.map(function (elem) {
return elem.sum;
});
Could you please tell me what am I doing wrong? thanks in advance
"reports": [
{
"id": 1,
"sum": 5221,
},
{
"id": 2,
"sum": 5421,
}
]

The data structure you provided was not complete or wrong. Considering it as a object you can use map and return the sum property
var a={"reports": [
{
"id": 1,
"sum": 5221,
},
{
"id": 2,
"sum": 5421,
}
]}
const doubles=a.reports.map((e)=>e.sum);
console.log(doubles)

Related

How to get distinct value from an array of objects containing array

I am trying to get an array of distinct values from the data structure below. I tried using reduce and object keys with no luck. What can I try next?
Data:
var data = [{
"id": 1,
"Technologies": ["SharePoint", "PowerApps"]
},
{
"id": 2,
"Technologies": ["SharePoint", "PowerApps", "SomethingElse"]
},
{
"id": 3,
"Technologies": ["SharePoint"]
},
{
"id": 4,
"Technologies": ["PowerApps"]
},
{
"id": 5,
"Technologies": null
}
]
Finished result should look like:
var distintValues = ["PowerApps", "SharePoint", "SomethingElse", null]
My attempt:
https://codepen.io/bkdigital/pen/MWEoLXv?editors=0012
You could use .flatMap() with a Set. .flatMap allows you to map each object's technology to one resulting array, and the Set allows you to remove the duplicates. With the help of optional chaining ?., you can also keep the null value (so it doesn't throw when accessing Technologies) like so:
const data = [{ "id": 1, "Technologies": ["SharePoint", "PowerApps"] }, { "id": 2, "Technologies": ["SharePoint", "PowerApps", "SomethingElse"] }, { "id": 3, "Technologies": ["SharePoint"] }, { "id": 4, "Technologies": ["PowerApps"] }, { "id": 5, "Technologies": null } ];
const res = [...new Set(data.flatMap(obj => obj?.Technologies))];
console.log(res);
[...new Set(
data
.map(v => Array.isArray(v.Technologies) ? v.Technologies : [v.Technologies])
.reduce((t, v) => [...t, ...v], [])
)];
I tried to solve this through JS. Here is my code:
const data = [{
"id": 1,
"Technologies": ["SharePoint", "PowerApps"]
}, {
"id": 2,
"Technologies": ["SharePoint", "PowerApps", "SomethingElse"]
}, {
"id": 3,
"Technologies": ["SharePoint"]
}, {
"id": 4,
"Technologies": ["PowerApps"]
}, {
"id": 5,
"Technologies": null
}]
const distintValues = [];
for (let element of data) {
if (element.Technologies != null) {
for (let elem of element.Technologies) {
if (!distintValues.includes(elem)) {
distintValues.push(elem);
}
}
}
}
console.log(distintValues);
In your attempt you tried to do it with reduce so here is how I would do it
var data = [{
"id": 1,
"Technologies": ["SharePoint", "PowerApps"]
},
{
"id": 2,
"Technologies": ["SharePoint", "PowerApps", "SomethingElse"]
},
{
"id": 3,
"Technologies": ["SharePoint"]
},
{
"id": 4,
"Technologies": ["PowerApps"]
},
{
"id": 5,
"Technologies": null
}
];
const objAsArray = Object.keys(data) // first we get the keys
.map(key => data[key]) // then we map them to their value
const technologyMap = objAsArray.reduce((acc, data) => {
// if the entry has technologies we set the key in the accumulation object to true
if (data.Technologies) {
data.Technologies.forEach(tech => acc[tech] = true)
}
return acc;
}, {})
// at the very end we get the keys of the accumulation object
const uniqueTechnologies =
Object.keys(
technologyMap
)

Sort by the sum of array in object

I am looking for a solution to sort an array by the sum of an array property within an object.
For example if the main array is
[
{
"Grid": {
"Day": [
11,
12
]
},
"Name": "One"
},
{
"Grid": {
"Day": [
5,
2
]
},
"Name": "Two"
}
]
How can I sort the sum of Day to return as
[
{
"Grid": {
"Day": [
5,
2
]
},
"Name": "Two"
},
{
"Grid": {
"Day": [
11,
12
]
},
"Name": "One"
}
]
You just need sort your array with comparator, that uses reduce to calc sum of inner array values:
let arr = [{"Grid": {"Day": [11,12]}, "Name": "One"},
{"Grid": {"Day": [5,2]}, "Name": "Two"},
{"Grid": {"Day": [1,2]}, "Name": "Two"}];
let sum = el => el.Grid.Day.reduce((a,b) => a + b);
arr.sort((a,b) => sum(a) - sum(b));
console.log(arr)
You can use a combination of reduce to sum the array, and sort to order the output:
var input = [
{
"Grid": {
"Day": [
11,
12
]
},
"Name": "One"
},
{
"Grid": {
"Day": [
5,
2
]
},
"Name": "Two"
}
];
var result = input.sort( (a,b) => sumOfDay(a) - sumOfDay(b));
console.log(result);
function sumOfDay(obj){
return obj.Grid.Day.reduce( (acc,curr) => acc + curr, 0);
}
Note that Array.prototype.sort actually mutates the original array in place. so the above could also do
input.sort( (a,b) => sumOfDay(a) - sumOfDay(b));
console.log(input);
So, don't fall into the trap of thinking the original array is unchanged just because I assigned the result to result!.
If you do wish to sort a copy of the array do this:
var result = input.slice().sort( (a,b) => sumOfDay(a) - sumOfDay(b));
Create a new Array of a by mapping through it and using reduce on the Day Array of Grid to get your sum which you can compare within a sort to return your list sorted by summed days.
const a = [
{
"Grid": {
"Day": [
11,
12
]
},
"Name": "One"
},
{
"Grid": {
"Day": [
5,
2
]
},
"Name": "Two"
}
]
const daySum = ({Grid}) => Grid.Day.reduce((prev, curr) => prev+curr, 0)
const sorted = [...a].sort(daySum)
console.log(sorted)
console.log(a) //Original array intact
Just "another" approach to solve the issue: assuming you (someday, later, eventually) may need to sort again, a good approach may also be to add a property to each grid item holding the sum of the days, avoiding the .reduce call every time you need to sort the array.
In this approach, .forEach is used to create the new property (through .reduce), and then .sort is used to sort the array in-place.
const input = [
{
"Grid": {
"Day": [
11,
12
]
},
"Name": "One"
},
{
"Grid": {
"Day": [
5,
2
]
},
"Name": "Two"
}
];
// Add a DaySum property evaluating the sum of the days.
input.forEach(i => i.Grid.DaySum = i.Grid.Day.reduce((a,b) => a + b));
// ^--- the second parameter (initial value) is unneeded here due to the fact that all elements are actually numeric, hence if the initial value is the first element of the array, which is a number already.
// Sor the array by that property.
input.sort((a,b) => a.Grid.DaySum - b.Grid.DaySum);
console.log(input);
Or, as suggested by #Andreas below, you can directly assign the property while sorting:
const input = [
{
"Grid": {
"Day": [
11,
12
]
},
"Name": "One"
},
{
"Grid": {
"Day": [
5,
2
]
},
"Name": "Two"
}
];
const sum = (a,b) => a + b;
input.sort((a,b) => {
a.Grid.DaySum = a.Grid.DaySum || a.Grid.Day.reduce(sum);
b.Grid.DaySum = b.Grid.DaySum || b.Grid.Day.reduce(sum);
return a.Grid.DaySum - b.Grid.DaySum;
});
console.log(input);

How to add new value inside array of object by id (not new item)

I'm trying add a new value inside my array by id. I'm not trying add a new item in my array... For this I can use push(), but it add new item not a new value.
I'm trying do it:
My array:
const data =
[
{
"id": 1,
"year":2019,
"value": 2,
},
{
"id": 2,
"year": 2019,
"value": 89,
},
{
"id": 3,
"year": 2019,
"value": 99,
}
]
Inside an especific id I would to add a new value like this:
data.forEach(item => {
if(item.id === 2){
//data inside id 2 -> item: 55
}
})
So my new dataarray looks like this:
const data =
[
{
"id": 1,
"year":2019,
"value": 2,
},
{
"id": 2,
"year": 2019,
"value": 89,
"item": 55
},
{
"id": 3,
"year": 2019,
"value": 99,
}
]
In most of my searches, I found just how to add a new element. But this I know how to do (push()).
So how to add a new value inside specified id?
Just assign the property you want to add:
data.forEach(item => {
if(item.id === 2){
item.item = 55;
}
})
If the IDs are unique, you can use the .find() method:
var el = data.find(item => item.id === 2);
if (el) {
el.item = 55;
}
try
data.find(x=> x.id==2).item=55;
const data =
[
{
"id": 1,
"year":2019,
"value": 2,
},
{
"id": 2,
"year": 2019,
"value": 89,
},
{
"id": 3,
"year": 2019,
"value": 99,
}
]
data.find(x=>x.id==2).item=55;
console.log(data);
You can iterate and assign value based on your criteria
data.map(function(x){
if(x.id == 2){
x.value = 100;
}
})
You can implement method using Array.find to avoid unnecessary iterations:
const array = [
{
"id": 1,
"year":2019,
"value": 2,
},
{
"id": 2,
"year": 2019,
"value": 89,
},
{
"id": 3,
"year": 2019,
"value": 99,
}
];
const changeValue = (array, id, field, value) =>
array.find(el => el.id === id)[field] = value;
changeValue(array, 1, 'year', 9999);
console.log('result: ', array);
You have an array of objects and you want to add a field to one of the objects. So, first, you have to find the object you want to change. Array items can be accessed by index, but you don't know the index. There are several methods to find an item in an array.
var item = data.find(function(d, i){
return item.id === 2; //criteria
});
or in ES6 syntax:
var item = data.find(d=>d.id == 2);
after that, you can change item the way you want.
item.anotherField = 'another value';
As you said, push() adds an item to the array. It doesn't change existing items in the array.
Your code is more or less right there. To set the property of an item, you can do either object.propertyName = ... or object["propertyName"] = ....
With that, you'd simply need to update your example to look like this:
data.forEach(item => {
if(item.id === 2){
item.item = 55; //data inside id 2 -> item: 55
}
})
As a more efficient alternative, consider Array.find(). It won't continue to loop through the array after it finds the id, whereas your forEach will always loop through the array in its entirety.
const data = [ { "id": 1, "year":2019, "value": 2, }, { "id": 2, "year": 2019, "value": 89, }, { "id": 3, "year": 2019, "value": 99, } ];
( data.find(({id})=> id === 2) || {} ).item = 55;
console.log(data);
You'll notice I've followed the .find() with || {}. This is simply so that if an item with id === 2 isn't found, attempting to set the property won't throw an error.

Add json Elements and values to Multiple json objects

I want combine a JSON object to an ARRAY.
I would like retrieve data from keys finded on var product, and combine score finded to a new variable ( combined results )
combinedresults is what I need. I absolutely don't know how to do this
var product = {
"presentation": 3,
"imgmax": http://test.com/img.jpg,
"puissance": 5,
"efficacite": 4,
"description": "This product is awesome but i need to combine JSON results"
}
var array = [
{
"caracname": "presentation",
"name": "Présentation"
},
{
"caracname": "efficacite",
"name": "Efficacité"
},
{
"caracnam": "puissance",
"name": "Puissance"
}
]
var combinedresults = [
{
"caracname": "presentation",
"name": "Présentation",
"score": 3
},
{
"caracname": "efficacite",
"name": "Efficacité",
"score": 4
},
{
"caracnam": "puissance",
"name": "Puissance",
"score": 5
}
]
Iterate through each item of the array, if the product object contains a key that matches the current items caracname, add it's value as a score.
See below:
var product = {
"presentation": 3,
"imgmax": "http://test.com/img.jpg",
"puissance": 5,
"efficacite": 4,
"description": "This product is awesome but i need to combine JSON results"
}
var array = [
{
"caracname": "presentation",
"name": "Présentation"
},
{
"caracname": "efficacite",
"name": "Efficacité"
},
{
"caracname": "puissance",
"name": "Puissance"
}
]
array.forEach(function(item) {
if (product[item.caracname]) {
item.score = product[item.caracname];
}
});
console.log(array);
Simply map over your current array, extending every object with the score attribute.
array.map(obj => ({...obj, score: product[obj.caracname]}));
If you are not familiar, consider having a look at the spread operator;

convert integer to array of object.

var items = [
{ "id": 1, "label": "Item1" },
{ "id": 2, "label": "Item2" },
{ "id": 3, "label": "Item3" }
];
I have this array of objects named 'items'. I get itemselected = 3 from the database.
I need to convert this 3 into the following form.
0:Object
id:3
label:"Item3"
Similarly, if i have a value 2 coming from the database, i should convert it to
0:Object
id:2
label:"Item2"
Can anyone please let me hint of how to get it solved. i am not here to get the answer. These questions are quite tricky for me and i always fail to get the logic right. Any advice on how to master this conversions will be of great help. thanks.
Since you tagged underscore.js, this should be very easy:
var selectedObject = _.findWhere(items, {id: itemselected});
Using ECMA6, you can achieve the same using .find method on arrays:
let selectedObject = items.find(el => el.id === itemselected);
With ECMA5, you can use filter method of arrays. Be careful that filter returns undefined if no element has been found:
var selectedObject = items.filter(function(el) { return el.id === itemselected});
Use jquery $.map function as below
$.map(item, function( n, i ) { if(n["id"] == 3) return ( n );});
Based on the title of your question: «convert integer to array of object». You can use JavaScript Array#filter.
The filter() method creates a new array with all elements that
pass the test implemented by the provided function.
Something like this:
var items = [{
"id": 1,
"label": "Item1"
},
{
"id": 2,
"label": "Item2"
},
{
"id": 3,
"label": "Item3"
}
];
var value = 2;
var result = items.filter(function(x) {
return x.id === value;
});
console.log(result); // Prints an Array of object.
Try this
var obj = {} ;
items = [
{ "id": 1, "label": "Item1" },
{ "id": 2, "label": "Item2" },
{ "id": 3, "label": "Item3" }
];
items.map(function(n) { obj[n.id] = n });

Categories

Resources