I have data like -
var data = [{"DefaultZone":[{"key":"stream0","value":100},
{"key":"stream1","value":50},
{"key":"stream2","value":10}
]},
{"Zone 1":[{"key":"stream0","value":120},
{"key":"stream1","value":55},
{"key":"stream2","value":15}
]}
]
and wanted to transform it like -
var data = [{"key": "stream0", "values":[{"x":"DefaultZone","y":100}, {"x":"Zone 1","y":120}]},
{"key": "stream1", "values":[{"x":"DefaultZone","y":50}, {"x":"Zone 1","y":55}]},
{"key": "stream2", "values":[{"x":"DefaultZone","y":10}, {"x":"Zone 1","y":15}]}
];
using JavaScript(ES6). Any help would be highly appreciated..
Here is the first way that came to mind:
var data = [{
"DefaultZone": [
{ "key": "stream0", "value": 100 },
{ "key": "stream1", "value": 50 },
{ "key": "stream2", "value": 10 }]
}, {
"Zone 1": [
{ "key": "stream0", "value": 120 },
{ "key": "stream1", "value": 55 },
{ "key": "stream2", "value": 15 }]
}];
let working = data.reduce((p, c) => {
let x = Object.keys(c)[0];
c[x].forEach(v => {
if (!p[v.key]) p[v.key] = [];
p[v.key].push({ x: x, y: v.value });
});
return p;
}, {});
let output = Object.keys(working).map(v => ({ key: v, values: working[v] }));
console.log(output);
Further reading:
the array .reduce() method
the Object.keys() method
the array .forEach() method
the array .map() method
Although I like nnnnnn's answer, here is another one, using only the Object.keys() method:
var data = [{
"DefaultZone": [{
"key": "stream0",
"value": 100
}, {
"key": "stream1",
"value": 50
}, {
"key": "stream2",
"value": 10
}]
}, {
"Zone 1": [{
"key": "stream0",
"value": 120
}, {
"key": "stream1",
"value": 55
}, {
"key": "stream2",
"value": 15
}]
}]
final = {}
data.forEach(function(x) {
Object.keys(x).forEach(function(y) {
x[y].forEach(function(z) {
if (!final[z['key']]) final[z['key']] = [];
final[z['key']].push({
'x': y,
'y': z['value']
})
})
})
})
answer = []
Object.keys(final).forEach(function(x) {
answer.push({
'key': x,
values: final[x]
})
})
console.log(answer)
Related
I have an array of objects like so:
arrayOfObjects = [
{
"name": "OneFullValue",
"value": 709
},
{
"name": "DRTG",
"value": 0
},
{
"name": "OtherFullValue",
"value": 345
},
{
"name": "TYU",
"value": 0
},
{
"name": "TRHY",
"value": 0
},
{
"name": "UOI",
"value": 0
},
]
End goal:
arrayOfObjectsEndGoal = [
{
"name": "OneFullValue",
"value": 709
},
{
"name": "DRTG - TYU - TRHY - UOI",
"value": 0
},
{
"name": "OtherFullValue",
"value": 345
}
]
Essentially, I want to group together all of the objects with the same value where the "name" key has the value of all of the names of the other objects separated by a -.
NOTE: THE VALUE CAN BE ANY NUMBER OTHER THAN 0, FOR EXAMPLE, IF I HAVE AN ARRAY LIKE SO:
arrayOfObjects = [
{
"name": "OneFullValue",
"value": 709
},
{
"name": "DRTG",
"value": 123
},
{
"name": "OtherFullValue",
"value": 345
},
{
"name": "TYU",
"value": 123
},
{
"name": "TRHY",
"value": 123
},
{
"name": "UOI",
"value": 123
},
]
End goal (we're not multiplying 123 by how many objects there are with value 123, we're just equating it):
arrayOfObjectsEndGoal = [
{
"name": "OneFullValue",
"value": 709
},
{
"name": "DRTG - TYU - TRHY - UOI",
"value": 123
},
{
"name": "OtherFullValue",
"value": 345
}
]
I know how to combine all of the objects together
arrayOfObjects.reduce(
((prev, oth) => Object.assign(prev, oth)), {}
)
I also know that I can use a foreach to loop through the array and manipulate the values:
let objItem = {};
let arrayOfObjectsEndGoal = [];
arrayOfObjects.foreach((obj) => {
if (objItem[obj.value]) {
let first = objItem[obj.name] -1;
let newValue = {
...arrayOfObjectsEndGoal[first]
};
arrayOfObjectsEndGoal[first] = newValue;
});
However, I'm unsure of how to move forwards to achieve the result. How can I combine objects like above?
You could add the names.
const
data = [{ name: "OneFullValue", value: 709 }, { name: "DRTG", value: 0 }, { name: "OtherFullValue", value: 345 }, { name: "TYU", value: 0 }, { name: "TRHY", value: 0 }, { name: "UOI", value: 0 }],
result = Object.values(data.reduce((r, { name, value }) => {
r[value] ??= { name: '', value };
r[value].name += (r[value].name && ' - ') + name;
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Hi I am getting data from API but I want my data in different format so that I can pass later into a function. I want to change the names of keys into a different one becasuse I have created a chart and it only draws if I send it data in certain way
This is what I am getting from API
data = {
"status": "success",
"from": "DB",
"indice": "KSE100",
"data": [
{
"stock_sector_name": "Tc",
"sector_score": "0828",
"stocks": [
{
"stock_symbol": "TRG",
"stock_score": 44
},
{
"stock_symbol": "SYS",
"stock_score": 33
}
]
},
{
"stock_sector_name": "OIL",
"sector_score": "0828",
"stocks": [
{
"stock_symbol": "FFS",
"stock_score": 44
},
{
"stock_symbol": "SMS",
"stock_score": 33
}
]
},
]
}
But I want my data to look like this like this
data = {
"name": "KSE100",
"children": [
{
"name": "A",
'points': -9,
"children": [
{
"stock_title": "A",
"value": 12,
},
{
"stock_title": "B",
"value": 4,
},
]
},
{
"name": "B",
'points': 20,
"children": [
{
"stock_title": "A",
"value": 12,
},
{
"name": "B",
"value": 4,
},
]
},
]
}
Like I want to replace
stock_sector_name = name
sector_score = value
stocks = children
stock_symbol = name
stock_score = value
I have been trying this for so much time but sill could not figured it out
function convert(d){
return {
name : d.indice,
children : d.data.map(y=>{
return {
name : y.stock_sector_name,
points : y.sector_score,
children : y.stocks.map(z=>{
return {
stock_title: z.stock_symbol,
value : z.stock_score
}
})
}
})
}
}
You can do something like this
const data = {
"status": "success",
"from": "DB",
"indice": "KSE100",
"data": [{
"stock_sector_name": "Tc",
"sector_score": "0828",
"stocks": [{
"stock_symbol": "TRG",
"stock_score": 44
},
{
"stock_symbol": "SYS",
"stock_score": 33
}
]
},
{
"stock_sector_name": "OIL",
"sector_score": "0828",
"stocks": [{
"stock_symbol": "FFS",
"stock_score": 44
},
{
"stock_symbol": "SMS",
"stock_score": 33
}
]
},
]
}
const data2 = {
"name": "KSE100",
"children": [{
"name": "A",
'points': -9,
"children": [{
"stock_title": "A",
"value": 12,
},
{
"stock_title": "B",
"value": 4,
},
]
},
{
"name": "B",
'points': 20,
"children": [{
"stock_title": "A",
"value": 12,
},
{
"name": "B",
"value": 4,
},
]
},
]
}
//stock_sector_name = name
//sector_score = value
//stocks = children
//stock_symbol = stock_title
//stock_score = value
const keys = {
stock_sector_name: "name",
sector_score: "points",
stocks: "children",
stock_symbol: "stock_title",
stock_score: "value",
indice: "name",
//data: "children"
}
const rename = (value) => {
if (!value || typeof value !== 'object') return value;
if (Array.isArray(value)) return value.map(rename);
return Object.fromEntries(Object
.entries(value)
.map(([k, v]) => [keys[k] || k, rename(v)])
);
}
renamedObj = rename(data);
console.log(renamedObj);
I have an array like this:
[
{
"costs": [{
"value": "80"
}],
"id": 4,
"name": "Subscription Fee",
"month": "March"
},
[
{
"costs": [{
"value": "200"
}],
"id": 2,
"name": "Tution",
"month": "March"
},
{
"costs": [{
"value": "10"
}],
"id": 11,
"name": "DEMO"
}
]
]
I need to have sumation of all the values from costs. How can i do that?
const data = [
{"costs":[{"value":"80"}],"id":4,"name":"Subscription Fee","month":"March"},
[
{"costs":[{"value":"200"}],"id":2,"name":"Tution","month":"March"},
{"costs":[{"value":"10"}],"id":11,"name":"DEMO"}
]
];
// flatten the arrays to get a list of objects
// iterate over this list
const res = data.flat().reduce((total, { costs = [] }) => {
// add the values of this item's costs with total
costs.forEach(({ value = 0 }) => total += +value);
return total;
}, 0);
console.log(res);
I'm facing some issue in for loop while creating an object from array of object.I have an array as this in node js app:
[
{
"Material": "113/133",
"Name": [
{
"name": "WELD1",
"value": 27520
},
{
"name": "WELD2",
"value": 676992
},
{
"name": "WELD3",
"value": 421
}
]
},
{
"Material": "150/300",
"Name": [
{
"name": "WELD1",
"value": 1441
},
{
"name": "WELD2",
"value": 555
},
{
"name": "WELD3",
"value": 100992
}
]
}
]
I want to return object like this which contains all the Material as array, Name and there value in array of object like this:
{
Material: ["113/133", "150/300"],
datasets: [
{
label: "WELD1",
data: [27520,1441]
},
{
label: "WELD2",
data: [676992,555]
},
{
label: "WELD3",
data: [100,20,0]
}
]
}
I want to get result using for loop.
you can use .reduce() and do something like this:
var arr = [
{
"Material": "113/133",
"Name": [
{
"name": "WELD1",
"value": 27520
},
{
"name": "WELD2",
"value": 676992
},
{
"name": "WELD3",
"value": 421
}
]
},
{
"Material": "150/300",
"Name": [
{
"name": "WELD1",
"value": 1441
},
{
"name": "WELD2",
"value": 555
},
{
"name": "WELD3",
"value": 100992
}
]
}
];
var newArr = arr.reduce((acc, ob) => {
for (var key in ob)
if(typeof acc[key] === 'object')
acc[key] = acc[key] ? acc[key].concat(ob[key]) : [ob[key]];
else
acc[key] ? acc[key].push(ob[key]) : acc[key] = [ob[key]];
return acc;
}, {});
console.log(newArr);
let array = [
{
"Material": "113/133",
"Name": [
{
"name": "WELD1",
"value": 27520
},
{
"name": "WELD2",
"value": 676992
},
{
"name": "WELD3",
"value": 421
}
]
},
{
"Material": "150/300",
"Name": [
{
"name": "WELD1",
"value": 1441
},
{
"name": "WELD2",
"value": 555
},
{
"name": "WELD3",
"value": 100992
}
]
}
]
let answer = {Material: [], datasets: []}
array.forEach(x => {
answer.Material.push(x.Material);
x.Name.forEach(na => {
let object = answer.datasets.find(obj => obj.label === na.name) || {label: "", data: []};
if(object.label === ""){
object.label = na.name;
object.data.push(na.value);
answer.datasets.push(object);
}else{
object.data.push(na.value)
}
});
});
console.log(answer);
The above is alternative solution using forEach instead of reduce
Use of Array.reduce to build your new data structure using data you have
const start = [{
"Material": "113/133",
"Name": [{
"name": "WELD1",
"value": 27520
},
{
"name": "WELD2",
"value": 676992
},
{
"name": "WELD3",
"value": 421
}
]
},
{
"Material": "150/300",
"Name": [{
"name": "WELD1",
"value": 1441
},
{
"name": "WELD2",
"value": 555
},
{
"name": "WELD3",
"value": 100992
}
]
}
];
const end = start.reduce((tmp, {
Material,
Name,
}) => {
// Handle the material
// If it do not exist in the array, push it
if (!tmp.Material.includes(Material)) {
tmp.Material.push(Material);
}
// Handle the datasets
// Look at each Name
Name.forEach(({
name,
value,
}) => {
// Can we find the label?
const labelFind = tmp.datasets.find(y => y.label === name);
// If we can't find the label, create a new dataset
if (!labelFind) {
tmp.datasets.push({
label: name,
data: [
value,
],
});
return;
}
// If we has found it push new value in the dataset
labelFind.data.push(value);
});
return tmp;
}, {
Material: [],
datasets: [],
});
console.log(end);
// This is the old fashioned way.
// Iterate over whole array,
// make a map, push value where 'name' is found in map
// later iterate over this map - dataMap - and form required datasets array.
var Material = [];
var dataMap = {};
arr.forEach(obj => {
Material.push(obj.Material);
obj.Name.forEach(item => {
if(dataMap[item.name]){
dataMap[item.name].push(item.value);
}
else {
dataMap[item.name] = [item.value];
}
});
});
var datasets = [];
Object.keys(dataMap).forEach(label => {
datasets.push({
label: label,
data: dataMap[label]
});
});
var result = {
Material: Material,
datasets: datasets
}
console.log(result);
I collect some json data. The actions on this data what i want to accomplished with d3js is the following:
Group data on the following json key's: "date" and "name"
Count the records wich match the above json keys
Return the result in a key value pair
JSON DATA
var expenses = [{"name":"jim","amount":34,"date":"11/12/2015"},
{"name":"carl","amount":120.11,"date":"11/12/2015"},
{"name":"jim","amount":45,"date":"12/01/2015"},
{"name":"stacy","amount":12.00,"date":"01/04/2016"},
{"name":"stacy","amount":34.10,"date":"01/04/2016"},
{"name":"stacy","amount":44.80,"date":"01/05/2016"}
];
I tried according the ( http://learnjsdata.com/group_data.html ) the following script:
var expensesTotalByDay = d3.nest()
.key(function(d) { return d.name; })
.key(function(d) { return d.date; })
.rollup(function(v) { return d3.sum(v, function(d) { return d.amount; }); })
.map(expenses);
But this results in:
{"jim":{"11/12/2015":34,"12/01/2015":45},
"carl":{"11/12/2015":120.11},
"stacy":{"01/04/2016":46.1,"01/05/2016":44.8}}
instead of(the expected result): EDITED 21:33
[
{
key: "jim", value:[
{
"key": "11/12/2015",
"value": 34
},
{
"key": "12/01/2015",
"value": 45
}
]
},
{
key: "carl", value:[
{
"key": "11/12/2015",
"value": 120.11
}
]
},
{
key: "stacy", value: [
{
"key": "01/04/2016",
"value": 12
},
{
"key": "01/04/2016",
"value": 34.1
},
{
"key": "01/05/2016",
"value": 44.8
}
]
}
]
I hope you can help me solve this issue.
Manny thanks
Erik
A proposal in plain Javascript with Array#forEach and a helper object.
var expenses = [{ "name": "jim", "amount": 34, "date": "11/12/2015" }, { "name": "carl", "amount": 120.11, "date": "11/12/2015" }, { "name": "jim", "amount": 45, "date": "12/01/2015" }, { "name": "stacy", "amount": 12.00, "date": "01/04/2016" }, { "name": "stacy", "amount": 34.10, "date": "01/04/2016" }, { "name": "stacy", "amount": 44.80, "date": "01/05/2016" }],
result = [];
expenses.forEach(function (a) {
if (!this[a.name]) {
this[a.name] = { key: a.name, value: [] };
result.push(this[a.name]);
}
this[a.name].value.push({ key: a.date, value: a.amount });
}, Object.create(null));
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');