javascript populate nested object from other nested object - javascript

I am rather new to JavaScript and I am following different tutorials at the moment. For visualisation of a d3js graph I like to restructure a small dataset so that the d3.layout.stack() function can deal with the data.
The original dataset looks as follows. Its an array of objects:
var dats = [{ apples: 5, oranges: 10, grapes: 22 },
{ apples: 4, oranges: 12, grapes: 28 },
{ apples: 2, oranges: 19, grapes: 32 },
{ apples: 7, oranges: 23, grapes: 35 },
{ apples: 23, oranges: 17, grapes: 43 }
];
The target object should look as follows. its an Array of Array of objects:
var finaldats = [
[{ x: 0, y: 5 },
{ x: 1, y: 4 },
{ x: 2, y: 2 },
{ x: 3, y: 7 },
{ x: 4, y: 23 }
],
[{ x: 0, y: 10 },
{ x: 1, y: 12 },
...
My approach so far:
var inner = {}
inner["x"] ;
inner["y"] ;
dats.forEach(function(d,i) {
inner["x"] = i
inner["y"] = dats[i].apples;
});
This produces: Object {x: 4, y: 23}
Its always the last element of the input array, which is fine, since the object is constantly overwritten in each iteration.
At the moment I fail to push these objects, being created in each iteration into an array.
I thought of something like this, but it does not work:
var inner = {}
inner["x"] ;
inner["y"] ;
var outer = [];
dats.forEach(function(d,i) {
inner["x"] = i
inner["y"] = dats[i].apples;
outer.push(inner);
});

Use map:
The map() method creates a new array with the results of calling a
provided function on every element in this array.
var dats = [{ apples: 5, oranges: 10, grapes: 22},
{ apples: 4, oranges: 12, grapes: 28},
{ apples: 2, oranges: 19, grapes: 32},
{ apples: 7, oranges: 23, grapes: 35},
{ apples: 23, oranges: 17, grapes: 43}
];
var inner = dats.map(function(d, i) {
return {
x: i,
y: d.apples
}
});
document.write('<pre>' + JSON.stringify(inner, 0, 4) + '</pre>');
Edit:
To get the result for all the Keys you can use below snippet:
var dats = [{ apples: 5, oranges: 10, grapes: 22},
{ apples: 4, oranges: 12, grapes: 28},
{ apples: 2, oranges: 19, grapes: 32},
{ apples: 7, oranges: 23, grapes: 35},
{ apples: 23, oranges: 17, grapes: 43}
];
var inner = dats.map((o) => {
return Object.keys(o)
}).reduce((prev, curr) => {
return prev.concat(curr)
}).filter((col, i, array) => {
return array.indexOf(col) === i
}).map(function(k) {
return dats.map(function(a, i) {
return {
x: i,
y: a[k]
};
});
});
document.write('<pre>' + JSON.stringify(inner, 0, 4) + '</pre>');
Read more about map

While the other solution features only a part of the solution, here the complete solution with an array for the keys and two nested Array#map(), one for the keys ['apples', 'oranges', 'grapes'] and one for the values in the dats.
var dats = [{ apples: 5, oranges: 10, grapes: 22 }, { apples: 4, oranges: 12, grapes: 28 }, { apples: 2, oranges: 19, grapes: 32 }, { apples: 7, oranges: 23, grapes: 35 }, { apples: 23, oranges: 17, grapes: 43 }],
finaldats = ['apples', 'oranges', 'grapes'].map(function (k) {
return dats.map(function (a, i) {
return { x: i, y: a[k] };
});
});
document.write('<pre>' + JSON.stringify(finaldats, 0, 4) + '</pre>');

Related

Having trouble accessing the nested values of my object. JavaScript

So I am trying to create a function that will list all the stats of a specific player in below object. I am simply trying to return the nested object associated with the playerName itself. I'm guessing map isn't working for me here. Instead I am returning an array of the individual letters of the name "Jeff Adrien". Can someone help me understand where I am going wrong?
//Code in question
function playerStats(playerName) {
let specificPlayer = allPlayers().players
if (playerName === specificPlayer) {
return specificPlayer
}
const stats = Object.values(playerName).map((nums) => {
return [nums]
})
return stats.flat()
}
console.log(playerStats('Jeff Adrien'))
// details
function allPlayers() {
const everyPlayer = Object.assign(homePlayers, awayPlayers)
return everyPlayer
}
const gameObject = () => {
return {
home: {
teamName: 'Brooklyn Nets',
colors: ['black', 'white'],
players: {
'Alan Anderson': {
number: 0,
shoe: 16,
points: 22,
rebounds: 12,
assists: 12,
steals: 3,
blocks: 1,
slamDunks: 1,
},
'Reggie Evans': {
number: 30,
shoe: 14,
points: 12,
rebounds: 12,
assists: 12,
steals: 12,
blocks: 12,
slamDunks: 7,
},
'Brook Lopez': {
number: 11,
shoe: 17,
points: 17,
rebounds: 19,
assists: 10,
steals: 3,
blocks: 1,
slamDunks: 15,
},
'Mason Plumlee': {
number: 1,
shoe: 19,
points: 26,
rebounds: 12,
assists: 6,
steals: 3,
blocks: 8,
slamDunks: 5,
},
'Jason Terry': {
number: 31,
shoe: 15,
points: 19,
rebounds: 2,
assists: 2,
steals: 4,
blocks: 11,
slamDunks: 1,
},
},
},
away: {
teamName: 'Charlotte Hornets',
colors: ['turquoise', 'purple'],
players: {
'Jeff Adrien': {
number: 4,
shoe: 18,
points: 10,
rebounds: 1,
assists: 1,
steals: 2,
blocks: 7,
slamDunks: 2,
},
'Bismak Biyombo': {
number: 0,
shoe: 16,
points: 12,
rebounds: 4,
assists: 7,
steals: 7,
blocks: 15,
slamDunks: 10,
},
'DeSagna Diop': {
number: 4,
shoe: 14,
points: 24,
rebounds: 12,
assists: 12,
steals: 4,
blocks: 5,
slamDunks: 5,
},
'Ben Gordon': {
number: 8,
shoe: 15,
points: 33,
rebounds: 3,
assists: 2,
steals: 1,
blocks: 1,
slamDunks: 0,
},
'Brendan Haywood': {
number: 33,
shoe: 15,
points: 6,
rebounds: 12,
assists: 12,
steals: 22,
blocks: 5,
slamDunks: 12,
},
},
},
}
}
wow I was trying to work with an array and turn it into an object somehow.. it just clicked for me
function playerStats(playerName) {
for (const player in allPlayers()) {
if (player === playerName) {
return allPlayers()[player]
}
}
}

How to select random object from JSON file in discord.js

I've done some searching around and I found some posts on here but my code doesn't want to work.
Basically I'm making a discord bot and I want to select an object from a JSON file at random.
This is my command:
const UserData = require('../data/users.js');
const monster = require('../data/monsters.json');
module.exports = {
name: 'battle',
aliases: ['fight'],
cooldown: 0,
description: 'User fights against a monster alone or in group',
execute(client, message, args) {
let enemy = monster[Math.floor(Math.random() * monster.length)]
UserData.findOne({
userID: message.author.id
}, (error, userdata) => {
if (error) console.log(error);
if (!userdata) {
return message.reply(`you don't have an account!`);
} else {
console.log(enemy);
return message.channel.send(`${enemy} spawned!`);
}
})
}
}
And this is my JSON file:
"1" : {
"name": "Blue Slime",
"hp": 20,
"atk": 12,
"def": 10,
"spatk": 3,
"spdef": 12,
"spd": 100,
"gold": 10,
"xp": 50,
"lvl": 1
},
"2": {
"name": "Red slime",
"hp": 20,
"atk": 12,
"def": 10,
"spatk": 3,
"spdef": 12,
"spd": 100,
"gold": 10,
"xp": 50,
"lvl": 1
},
"3": {
"name": "Green slime",
"hp": 20,
"atk": 12,
"def": 10,
"spatk": 3,
"spdef": 12,
"spd": 100,
"gold": 10,
"xp": 50,
"lvl": 1
}
}
If I want put the objects in the command manually and then randomly select them it works and if instead of "monster.length" I put a number then it also works but I still get undefined if it should be 3.
This way I also always get undefined in console log from monster.length.
What am I doing wrong?
Your monsters.json file contains an object and objects don't have lengths. You can however convert it to an array, using Object.values() that returns an array of the given object's own enumerable property values.
Check out the snippet below:
let monsters = {
1: {
name: 'Blue Slime',
hp: 20,
atk: 12,
def: 10,
spatk: 3,
spdef: 12,
spd: 100,
gold: 10,
xp: 50,
lvl: 1,
},
2: {
name: 'Red slime',
hp: 20,
atk: 12,
def: 10,
spatk: 3,
spdef: 12,
spd: 100,
gold: 10,
xp: 50,
lvl: 1,
},
3: {
name: 'Green slime',
hp: 20,
atk: 12,
def: 10,
spatk: 3,
spdef: 12,
spd: 100,
gold: 10,
xp: 50,
lvl: 1,
},
};
function randomObject(obj) {
let arr = Object.values(obj);
return arr[Math.floor(Math.random() * arr.length)];
}
let enemy = randomObject(monsters);
console.log(enemy);

How to subtract or minus from two array of objects particular values?

To be silly I am here to ask a simple question which make me too much time
Here is sample data
const demo1 = [
{ count: 156, monthCount: 1, year: 2018 },
{ count: 165, monthCount: 2, year: 2018 },
{ count: 103, monthCount: 3, year: 2018 },
{ count: 60, monthCount: 4, year: 2018 }
]
const data2 = [
{ count: 100, monthCount: 1, year: 2019 },
{ count: 55, monthCount: 2, year: 2019 },
{ count: 99, monthCount: 3, year: 2019 },
{ count: 130, monthCount: 4, year: 2019 }
]
I want to get data3 which is data2 - data1 with its key
Expected Out put look like that
[
{count: 56, monthCount: 1 },
{count: 100, monthCount: 2 },
{count: 60, monthCount: 3 },
{count: 70, monthCount: 4 }
]
If you want to subtract data2 - data1, then you can do it through vanilla JavaScript. Let me show an example.
Your data:
const data1 = [
{ count: 156, monthCount: 1, year: 2018 },
{ count: 165, monthCount: 2, year: 2018 },
{ count: 103, monthCount: 3, year: 2018 },
{ count: 60, monthCount: 4, year: 2018 }
];
const data2 = [
{ count: 100, monthCount: 1, year: 2019 },
{ count: 55, monthCount: 2, year: 2019 },
{ count: 99, monthCount: 3, year: 2019 },
{ count: 130, monthCount: 4, year: 2019 }
];
An example:
const combined = data1.concat(data2);
console.log(`combined, not calculated`, combined);
const desired = [...combined.reduce((r, {monthCount, count}) => {
const key = monthCount;
const item = r.get(key) || Object.assign({}, {
count: 0,
monthCount: monthCount
});
if (item.count === 0)
item.count = -count;
else
item.count += +count;
return r.set(key, item);
}, new Map).values()];
console.log(`desired: `, desired)
OUTPUT:
[
{count: -56, monthCount: 1},
{count: -110, monthCount: 2},
{count: -4, monthCount: 3},
{count: 70, monthCount: 4},
]
const data1 = [
{ count: 156, monthCount: 1, year: 2018 },
{ count: 165, monthCount: 2, year: 2018 },
{ count: 103, monthCount: 3, year: 2018 },
{ count: 60, monthCount: 4, year: 2018 }
]
const data2 = [
{ count: 100, monthCount: 1, year: 2019 },
{ count: 55, monthCount: 2, year: 2019 },
{ count: 99, monthCount: 3, year: 2019 },
{ count: 130, monthCount: 4, year: 2019 }
];
const subtractData = (arrOne, arrTwo) => {
const newArr = []
arrOne.forEach((elOne) => {
arrTwo.forEach((elTwo) => {
if(elOne.monthCount === elTwo.monthCount){
const count = Math.abs(Number(elOne.count) - Number(elTwo.count));
const newObj = {
...elOne,
count
}
delete newObj.year;
newArr.push(newObj)
}
})
})
return newArr;
}
console.log(subtractData(data1, data2))

group and restructure json data using javascript [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have this data where I don't have control to format or do any changes
//input json data
[
{
"Breaks":[
{"points":12,"points_total":12,"average":8.0,"faults":[]},
{"points":17,"points_total":29,"average":11.6,"faults":[]},
{"points":6,"points_total":35,"average":11.6667,"faults":[]},
{"points":8,"points_total":43,"average":10.75,"faults":[]},
{"points":14,"points_total":57,"average":11.4,"faults":[]},
],
"team_name":"King Sports"
},
{
"Breaks":[
{"points":18,"points_total":18,"average":15.4286,"faults":[]},
{"points":2,"points_total":20,"average":10.0,"faults":[]},
{"points":7,"points_total":27,"average":9.0,"faults":[]},
{"points":9,"points_total":36,"average":9.0,"faults":[]},
{"points":4,"points_total":40,"average":8.0,"faults":[]},
{"points":4,"points_total":44,"average":7.33333,"faults":[]},
{"points":4,"points_total":48,"average":6.85714,"faults":[]},
{"points":8,"points_total":56,"average":7.0,"faults":[]},
{"points":1,"points_total":57,"average":6.33333,"faults":[]},
{"points":6,"points_total":63,"average":6.3,"faults":[]},
{"points":3,"points_total":66,"average":5.82353,"faults":[]},
{"points":6,"points_total":72,"average":6.0,"faults":[]},
{"points":7,"points_total":79,"average":6.07692,"faults":[]},
{"points":3,"points_total":82,"average":5.85714,"faults":[]},
{"points":0,"points_total":82,"average":5.65517,"faults":[]}
],
"team_name":"Lion Sports"
}
]
So, I need to rebuild/restructure it to get following result.
There will be 20 "Breaks" if no value found in "Breaks" till it reaches to 20 then it should have "null" values.
//the result what i wanted = output expected
[
['Breaks', 'King Sports', 'Lion Sports'],
['1', 12, 18],
['2', 29, 20],
['3', 35, 27],
['4', 43, 36],
['5', 57, 40],
['6', null, 44],
['7', null, 48],
['8', null, 56],
['9', null, 57],
['10', null, 63],
['11', null, 66],
['12', null, 72],
['13', null, 79],
['14', null, 82],
['15', null, null],
['16', null, null],
['17', null, null],
['18', null, null],
['19', null, null],
['20', null, null]
]
You could generate the result array first and the put the values in.
var data = [{ Breaks: [{ points: 12, points_total: 12, average: 8.0, faults: [] }, { points: 17, points_total: 29, average: 11.6, faults: [] }, { points: 6, points_total: 35, average: 11.6667, faults: [] }, { points: 8, points_total: 43, average: 10.75, faults: [] }, { points: 14, points_total: 57, average: 11.4, faults: [] }], team_name: "King Sports" }, { Breaks: [{ points: 18, points_total: 18, average: 15.4286, faults: [] }, { points: 2, points_total: 20, average: 10.0, faults: [] }, { points: 7, points_total: 27, average: 9.0, faults: [] }, { points: 9, points_total: 36, average: 9.0, faults: [] }, { points: 4, points_total: 40, average: 8.0, faults: [] }, { points: 4, points_total: 44, average: 7.33333, faults: [] }, { points: 4, points_total: 48, average: 6.85714, faults: [] }, { points: 8, points_total: 56, average: 7.0, faults: [] }, { points: 1, points_total: 57, average: 6.33333, faults: [] }, { points: 6, points_total: 63, average: 6.3, faults: [] }, { points: 3, points_total: 66, average: 5.82353, faults: [] }, { points: 6, points_total: 72, average: 6.0, faults: [] }, { points: 7, points_total: 79, average: 6.07692, faults: [] }, { points: 3, points_total: 82, average: 5.85714, faults: [] }, { points: 0, points_total: 82, average: 5.65517, faults: [] }], team_name: "Lion Sports" }],
result = data.reduce(function (r, a, i) {
r[0][i + 1] = a.team_name;
a.Breaks.forEach(function (b, j) {
r[j + 1][i + 1] = b.points_total;
});
return r;
}, function (length) {
var a = Array.apply(null, { length: length + 1 }).map(function (_, i) { return [(i || 'Breaks').toString(), null, null] });
return a;
}(20));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to interpolate missing values in my chart?

I used this code (JSFiddle: http://jsfiddle.net/0zvq3gr7/):
var data = [
{ Date: "2015-09-14", DayOfMonth: 14, Type: "Views", Amount: 5, y1: 10, },
{ Date: "2015-09-14", DayOfMonth: 14, Type: "Likes", Amount: 2, y1: 15, },
{ Date: "2015-09-15", DayOfMonth: 15, Type: "Views", Amount: 10, y1: 35, },
// { Date: "2015-09-15", DayOfMonth: 15, Type: "Likes", Amount: 4, y1: 20, },
{ Date: "2015-09-16", DayOfMonth: 16, Type: "Views", Amount: 14, y1: 22, },
{ Date: "2015-09-16", DayOfMonth: 16, Type: "Likes", Amount: 10, y1: 22, },
{ Date: "2015-09-17", DayOfMonth: 27, Type: "Views", Amount: 20, y1: 22, },
{ Date: "2015-09-17", DayOfMonth: 27, Type: "Likes", Amount: 12, y1: 22, },
];
var svgWidth = $("#chart").width(),
svgHeight = $("#chart").height();
var svg = dimple.newSvg("#chart", svgWidth, svgHeight);
var chart = new dimple.chart(svg, data);
var xAxis = chart.addCategoryAxis("x", "DayOfMonth");
xAxis.title = null;
xAxis.addOrderRule("Date");
var yAxis = chart.addMeasureAxis("y", "Amount");
yAxis.title = null;
var series = chart.addSeries("Type", dimple.plot.area);
series.stacked = false;
//series.interpolation = "cardinal";
var legend = chart.addLegend(0, 20, 300, 20, "right");
chart.draw();
The result is this:
In the previous example I removed:
{ Date: "2015-09-15", DayOfMonth: 15, Type: "Likes", Amount: 4, y1: 20, }
from the data. Since for the "Likes" Type DayOfMonth 15 is missing there should be a straight line between DayOfMonth 14 and 16 for "Likes". I draw this in the following graphic:
How do I fix the wrong interpolation here?
You have two objects for DayOfMonth 15 . If you remove them both it will draw a linear line between 14 and 16. Look at this updated fiddle.
var data = [
{ Date: "2015-09-14", DayOfMonth: 14, Type: "Views", Amount: 5, y1: 10, },
{ Date: "2015-09-14", DayOfMonth: 14, Type: "Likes", Amount: 2, y1: 15, },
// { Date: "2015-09-15", DayOfMonth: 15, Type: "Views", Amount: 10, y1: 35, },
// { Date: "2015-09-15", DayOfMonth: 15, Type: "Likes", Amount: 4, y1: 20, },
{ Date: "2015-09-16", DayOfMonth: 16, Type: "Views", Amount: 14, y1: 22, },
{ Date: "2015-09-16", DayOfMonth: 16, Type: "Likes", Amount: 10, y1: 22, },
{ Date: "2015-09-17", DayOfMonth: 27, Type: "Views", Amount: 20, y1: 22, },
{ Date: "2015-09-17", DayOfMonth: 27, Type: "Likes", Amount: 12, y1: 22, },
];

Categories