how to assign json strings from same dataset to different variables - javascript

I have a data set which has a number of devices with similar properties (output). (for example 2 given below). what I do not understand is how do I take each device with the new name and assign it to for example a new div. There can be many devices in dataset. How do I tell my code to whenever there is a new device take out bytes_read and bytes_written and assign them to a new div for example assign
"bdev0": {"Bytes_Read": 0, "Bytes_Written": 0} to div_one
"bdev1": {"Bytes_Read": 10, "Bytes_Written": 20 } to div_two
Note that I cannot use something like data.devices[0] because there are many devices and their names keep changing, e.g bdev0, bdev1, bdev2, bde3..
here is the sample of dataset given:
var data = {
"devices": [
{
"Name": "bdev0",
"output": {
"IO_Operations": 0,
"Bytes_Read": 0,
"Bytes_Written": 0
}
},
{
"Name": "bdev1",
"output": {
"IO_Operations": 10,
"Bytes_Read": 20,
"Bytes_Written": 30
}
}
]
}
This is how far I could come but it creates two different strings but how do I assign these separately to two different items. it sounds really stupid but I am really stuck here if for example I want to assign these strings to var a and var b how should I do it
function myData() {
for (var i in data.devices){
var obj = new Object();
obj.Bytes_read = data.devices[i].output.Bytes_Read;
obj.Bytes_written = data.devices[i].output.Bytes_Written;
var jsonString= JSON.stringify(obj);
console.log(jsonString)
}
}
myData(data)
Result
{"Bytes_read":0,"Bytes_written":0}
{"Bytes_read":20,"Bytes_written":30}
It gives me the data I want but I cannot figure out to assign these sets to var a and var b.

If you have the name of the device you can use it as key for the access of the data.
var data = {
"devices": [{
"Name": "bdev0",
"output": {
"IO_Operations": 0,
"Bytes_Read": 0,
"Bytes_Written": 0
}
}, {
"Name": "bdev1",
"output": {
"IO_Operations": 10,
"Bytes_Read": 20,
"Bytes_Written": 30
}
}]
},
selectedData = {};
data.devices.forEach(function (a) {
selectedData[a.Name] = {
Bytes_Read: a.output.Bytes_Read,
Bytes_Written: a.output.Bytes_Written
};
});
document.write('<pre>'+JSON.stringify(selectedData, 0, 4)+'</pre>');
Update: Maybe this is what you want. With the name of the device, the function getDeviceInfo returns the information.
function getDeviceInfo(deviceName) {
var obj = {};
data.devices.some(function (a) {
if (a.Name === deviceName) {
obj[deviceName] = {
Bytes_Read: a.output.Bytes_Read,
Bytes_Written: a.output.Bytes_Written
};
return true;
}
});
return obj;
}
var data = {
"devices": [{
"Name": "bdev0",
"output": {
"IO_Operations": 0,
"Bytes_Read": 0,
"Bytes_Written": 0
}
}, {
"Name": "bdev1",
"output": {
"IO_Operations": 10,
"Bytes_Read": 20,
"Bytes_Written": 30
}
}]
},
div_one = getDeviceInfo('bdev0'),
div_two = getDeviceInfo('bdev1');
document.write('<pre>' + JSON.stringify(div_one, 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(div_two, 0, 4) + '</pre>');

I'm not quite sure what you're trying to achieve. The code below will take the output property of each element in array and set a to its value when Name is bdev0, and b to it otherwise. I hope this is what you needed:
var a, b;
if (data[0]['Name'] === 'bdev0') {
a = JSON.stringify(data[0]['output']); // bdev0
b = JSON.stringify(data[1]['output']); // bdev1
} else {
a = JSON.stringify(data[1]['output']); // bdev1
b = JSON.stringify(data[0]['output']); // bdev0
}

Related

Sort a Json by user.id from a JSON

I have a JSON in which I save the GuildID and then again the UserID
"385524088980111362": {
"672748733737467936": {
"XP": 0,
"Level": 1,
"BisLevel": 100,
"NächsteXP": 0,
"XPIns": 2
},
"866935358448468008": {
"XP": 0,
"Level": 1,
"BisLevel": 100,
"NächsteXP": 0,
"XPIns": 7
}
}
Now I want to sort the users by XPIns from one Guild. I remember this code part here
let obj;
fs.readFile('./xpdata.json', 'utf8', function (err, data) {
if (err) throw err;
obj = JSON.parse(data)
var sorted = Object.entries(obj).sort((a, b) => b[1] - a[1])
});
In the end, the user with more should be in the 1st position (866935358448468008). Can anyone help me?
I've seen a similar question before but couldn't get it to work if there was a GuildID in front of it
The code I had done before (sorry for the sloppy code that was a year ago (Code is updated)):
let obj;
fs.readFile('./userdata.json', 'utf8', function (err, data) {
if (err) throw err;
try {
obj = JSON.parse(data)
} catch (error) {
if(error) return console.log("Ein Fehler ist aufgetreten! " + error);
}
var sorted = Object.entries(obj).sort((a, b) => b[1].Economy.Balance - a[1].Economy.Balance)
if(sorted.length > 10) sorted = sorted.slice(0, 10)
var lBString = "";
var s = 1;
sorted.forEach(user => {
let usertag = Data[user[0]].Tag
lBString += `${s}. ${usertag} • **${user[1].Economy.Balance}$**\n`
s = s += 1
})
let embed = {
title: `Leaderboard Balance`,
description: lBString,
color: 0xFFFF00,
thumbnail: {
url: client.user.avatarURL(),
},
timestamp: new Date(),
footer: {
text: footer,
icon_url: client.user.avatarURL(),
},
}
e.reply({embeds: [embed]});
});
If you simply want the highest ranking user in terms of "XPIns", I suggest you use a Array.reduce() call on the entries of the inner object.
const data = {
"385524088980111362": {
"672748733737467936": {
"XP": 0,
"Level": 1,
"BisLevel": 100,
"NächsteXP": 0,
"XPIns": 2
},
"866935358448468008": {
"XP": 0,
"Level": 1,
"BisLevel": 100,
"NächsteXP": 0,
"XPIns": 7
}
}
};
const topUser = Object.entries(data['385524088980111362']).reduce((acc, cur) => (
acc[1]?.XPIns > cur[1]?.XPIns ? acc : cur
), []);
console.log(topUser);
What I do in cases like this is to use another object as index using a reference of the main array/object
ie:
var index = {};
// replace .id with the attribute you want to use. In your case XPins
index[ object.id ] = main_index_reference;
once you have generated the index, then you can get the keys using Object.keys( index ):
var keys = Object.keys( index );
keys.forEach( function( key ){
var element = main_object[ key ];
// do whatever with the element
} );
Your main_object remains unchanged. In your particular case you want the highest value, all you need to do is to extract the last element from the keys array.
You can try with this. However, the users do not have their ID inside their object, so you'd probably have to patch the ID before sorting.
const data = {
// if the guild could have list of users then it would have been much better
// instead of Object list with ID, Array of objects with ID in it works much faster..
"385524088980111362": {
"672748733737467936": {
// if we had user ID here, then it would have been better
"XP": 0,
"Level": 1,
"BisLevel": 100,
"NächsteXP": 0,
"XPIns": 2
},
"866935358448468008": {
"XP": 0,
"Level": 1,
"BisLevel": 100,
"NächsteXP": 0,
"XPIns": 7
}
}
};
function getSortedUsersByXPins(data, guildId) {
// if guild has array of users, then we won't need Object.values
const sorted = Object.values(data[guildId]).sort((user1, user2) => {
return user2.XPins - user1.XPins
});
return sorted;
}
const sorted = getSortedUsersByXPins(data, '385524088980111362');
console.log(sorted)
You can try it with this solution, in case you want to convert the object to a list. The main issue is the missing identifier if you work with a list.
This assumes that you would use a function like Object.entries before to convert it.
My recommendation: Include the id into the object and convert it to a list.
let guildList = [
{
"XP": 0,
"Level": 1,
"BisLevel": 100,
"NächsteXP": 0,
"XPIns": 2,
"Id": "672748733737467936"
},
{
"XP": 0,
"Level": 1,
"BisLevel": 100,
"NächsteXP": 0,
"XPIns": 7,
"Id": "866935358448468008"
}
];
let aSorted = guildList.sort((a, b) => b.XPIns-a.XPIns)
console.log(aSorted)
Just extract the player objects and sort them, pretty much the way you already described ((p1, p2) => p2.XPIns - p1.XPIns).
Here is an example:
const data = {
"385524088980111362": {
"672748733737467936": {
"XP": 0,
"Level": 1,
"BisLevel": 100,
"NächsteXP": 0,
"XPIns": 2
},
"866935358448468008": {
"XP": 0,
"Level": 1,
"BisLevel": 100,
"NächsteXP": 0,
"XPIns": 7
}
}
}
const res = Object.fromEntries(Object.entries(data).map( ([gid, users]) => [gid, Object.entries(users).map(([id, u]) => ({id, ...u })).sort( (u1, u2) => u2.XPIns - u1.XPIns)] ))
console.log(res)
Note that you cannot create an object with player id as key without losing the order, since JS objects always put numeric keys in ascending order.

javascript grouping linked nodes

I have 2 lists - nodes and links... Now what I would want is the most efficient way to add all the directly/indirectly linked elements into different groups.... For eg, 0 is connected to 1 which is connected to 2 so nodes 0,1,2 become group 1.... node 3 is connected to 4 so it becomes group 2 and so on.... Thanks in advance for your help :) This is part of a d3 implementation am doing..
PS: These lists will easily be in tens of thousands of nodes and links.
"nodes":[
{
"id":0,
"x":1509.9862,
"y":-609.1013
},
{
"id":1,
"x":1645.9578,
"y":-85.06705
},
{
"id":2,
"x":1948.1533,
"y":-469.3646
},
{
"id":3,
"x":348.1533,
"y":-669.3646
},
{
"id":4,
"x":1448.1533,
"y":-1469.3646
}
...
]
"links":[
{
"from":0,
"to":1
},
{
"from":1,
"to":2
},
{
"from":3,
"to":4
}
...
]
This is a classic UnionFind problem. The idea is to see each node as a set that has a pointer point to its father. Nodes with the same father are in the same group. So for your problem, we can create n sets at the beginning. And then iterate through the link to group everyone connected by the same link. The complexity is O(n), where n is the number of nodes.
nodes = [{
"id": 0,
"x": 1509.9862,
"y": -609.1013
},
{
"id": 1,
"x": 1645.9578,
"y": -85.06705
},
{
"id": 2,
"x": 1948.1533,
"y": -469.3646
},
{
"id": 3,
"x": 348.1533,
"y": -669.3646
},
{
"id": 4,
"x": 1448.1533,
"y": -1469.3646
}
];
links = [{
"from": 0,
"to": 1
},
{
"from": 1,
"to": 2
},
{
"from": 3,
"to": 4
}
];
// union-find is a data structure that can union two sets and check
// whether two element in the same set.
var father = {};
function group(nodes, links) {
// create n set with each set has the node as its only element
nodes.forEach(function(node, i) {
father[node.id] = node.id;
});
// union each set that has a link between them
links.forEach(function(link, i) {
union(link.from, link.to);
});
// for each unioned set, group nodes together
var id = 1;
var groupIdCnt = {};
var groupIds = {};
nodes.forEach(function(node, i) {
var f = find(node.id);
if (typeof groupIds[f] === 'undefined') {
groupIds[f] = id;
groupIdCnt[id] = 1;
id++;
} else {
groupIdCnt[groupIds[f]]++;
}
});
var groups = {};
nodes.forEach(function(node, i) {
var f = find(node.id);
if (groupIdCnt[groupIds[f]] === 1) {
node['group'] = 0;
} else {
node['group'] = groupIds[f];
}
if (typeof groups[node['group']] === 'undefined') {
groups[node['group']] = [];
}
groups[node['group']].push(node);
});
return Object.values(groups);
}
// find father of each set
function find(node) {
// if it is the root, return
if (father[node] === node) {
return node;
}
// if not, find the father and point to it
father[node] = find(father[node]);
return father[node];
}
// update the father of set which includes node1 to the father of set which includes node 2
function union(node1, node2) {
father[find(node1)] = find(node2);
}
// O(n), since we visit each node once
var groups = group(nodes, links);
console.log(nodes);
console.log(groups);
This code spits out an object whose keys are the node id and whose values are a group id, not necessarily sequential.
var obj = {
"links":[
{
"from":0,
"to":1
},
{
"from":1,
"to":2
},
{
"from":5,
"to":4
},
{
"from":3,
"to":4
}
]
};
var groups = {};
var nextGrp = 1;
for (var i=0, l; l = obj.links[i]; i++) {
if (groups[l.from]) {
if (groups[l.to]) {
if (groups[l.to] != groups[l.from]) {
// the two items span two different groups which must now be joined into 1
for (var j in groups) {
if (groups[j] == groups[l.to]) {
groups[j] = groups[l.from];
}
}
}
} else {
groups[l.to] = groups[l.from];
}
} else if (groups[l.to]) {
groups[l.from] = groups[l.to];
} else {
groups[l.from] = nextGrp;
groups[l.to] = nextGrp;
nextGrp++;
}
}
console.log(groups);
In the solution below I am creating groups of links that are, well, linked to each other. I do so by looping through all of the from/to combinations, and finding out if either has already been added to any of the accumulating groups of links. If they have, then I just add (or re-add) both the from and to value to that group. If neither the from nor to value has yet been grouped, then I make a new group and add both the from and to values to it. Note that these "groups" are actually Javascript sets, a new ES6/ES2015 data type that makes it much easier to deal with "groups" of elements for which no duplicates are needed and/or allowed.
Once the groups/sets of links are established, I then simply add an attribute to each node that indicates which group of links it is a part of.
Note that, for the sake of this demo code, I've simplified/de-cluttered some node values. I've also added some extra links, just to demonstrate some further cases that need handling.
const groupNodes = (nodes, links) => {
const groups = links.reduce((grps, {from, to}) => {
if (!grps.some(grp => {
if (grp.has(from) || grp.has(to)) return grp.add(from).add(to);
})) grps.push(new Set([from, to]));
return grps;
}, []);
nodes.forEach(node => {
groups.forEach((grp, i) => { if (grp.has(node.id)) node.group = i; });
});
return nodes;
};
const nodes = [
{
"id":0,
"x":0,
"y":0
},
{
"id":1,
"x":11,
"y":-11
},
{
"id":2,
"x":22,
"y":-22
},
{
"id":3,
"x":33,
"y":-33
},
{
"id":4,
"x":44,
"y":-44
},
{
"id":5,
"x":55,
"y":-55
},
{
"id":6,
"x":66,
"y":-66
}
];
const links = [
{
"from": 0,
"to" : 1
},
{
"from": 1,
"to" : 2
},
{
"from": 2,
"to" : 0
},
{
"from": 3,
"to" : 4
},
{
"from": 4,
"to" : 5
},
{
"from": 6,
"to" : 0
}
];
console.log(JSON.stringify(groupNodes(nodes, links)));

JavaScript - Processing and restructuring JSON not working

I'm trying to process a json file and create a new one, but it does not work.
The structure of an old json is something like this:
[
{
"3":{
"value":2
},
"4":{
"value":1
}
},
{
"3":{
"value":6
},
"4":{
"value":1
}
}...and so on
What I'm trying to do is to create a new json object, which will have only two objects 0 and 1 and inside each of them there will be values from indexes 3 and 4 from the old one, which should look something like this:
{
"0":{
"0":[
{
"0":2
}
],
"1":[
{
"0":6
}
]..and so on
},
"1":{
"0":[
{
"0":1
}
],
"1":[
{
"0":1
}
]..and so on
}
}
The problem is that when I process and cook the old json the output for both indexes(0,1) is the same. I'm trying to loop it through 3 and 4 and assign those values into the new array but something is not quite right.
Fraction of the code:
//loop through the keysIndex
for (var c in keysIndex) {
//the new json has to be 2 objects, hence the below
newData[c] = {};
var vallueArr = [];
var newObj = {
0: oldData[i][keysIndex[c]].value
}
vallueArr.push(newObj);
objInNewData[entries] = vallueArr;
//the problem is somehwere here, it is appending twice the same
//objInNewData and not both 3 and 4 individually
newData[c] = objInNewData;
}
Hers's the whole logic: PLUNKER
Can someone please help as I cannot get my head around this :(
Many thanks
As I mentioned above, the use of index of keys of objects is not a good idea, because objects in Javascript have no defined order. For ordered items I suggest to use an array instead.
var data = [
{
"3": { "value": 2 },
"4": { "value": 1 }
}, {
"3": { "value": 6 },
"4": { "value": 1 }
}
],
keys = Object.keys(data[0]), // <-- ATTENTION!
obj = {};
data.forEach(function (a, i) {
keys.forEach(function (k, j) {
obj[j] = obj[j] || {};
obj[j][i] = obj[j][i] || [];
obj[j][i].push({ '0': a[k].value });
});
});
document.write('<pre>' + JSON.stringify(obj, 0, 4) + '</pre>');

Javascript Populate key value with value is an array

I want to iterate over a JSON in javasacript and create something like this as output
{
"seriesData": [
{
"name": "John",
"data": [
5,
3,
4
]
},
{
"name": "Jane",
"data": [
2,
2,
3
]
},
{
"name": "Joe",
"data": [
3,
4,
4
]
}
]
}
So, I essentially need to add values in data array for each key inside my for loop.
Input looks like:
{"Records":[{"name":"Jan'10","users":[{"name":"John","y":5},{"name":"Jane","y":2},{"name":"Joe","y":3}]},{"name":"Jan'10","users":[{"name":"John","y":3},{"name":"Jane","y":2},{"name":"Joe","y":4}]},{"name":"Jan'10","users":[{"name":"John","y":4},{"name":"Jane","y":3},{"name":"Joe","y":4}]}]};
Can someone please suggest how can this be achieved.
you could try something like this:
var dataList = {};
function addData(name){
if( dataList[name] == undefined)
dataList[name] = [];
for (var i = 1; i < arguments.length; i++) {
dataList[name].push(arguments[i]);
}
}
function packData(){
var pack = []
for(var e in dataList){
pack.push({
name: e,
data:dataList[e].sort(function(a,b){return a-b})
});
}
return pack;
}
addData("Joe", 1);
addData("Jan", 2, 10);
addData("Joe", 3, 5, 10, 18, 500);
addData("Jan", 4);
addData("Joe", 5);
addData("Jan", 6);
console.log( packData() );
use addData(name, data); to append data to a name and afterwards pack this data with packData()
EDIT:
Sry switched to PHP for a while... fixed the script XD

Create an object with custom structure in javascript

I need to create an array object with this exact structure:
{"item1": {
0 : {
color:"description1",
width:"description2",
height:"description3"
}
1 : {
color:"description1",
width:"description2",
height:"description3"
}
//and so on
},
"item2": {
0 : {
color:"description1",
width:"description2",
height:"description3"
}
//and so on
}
//and so on
}
Estatically works fine. Now, I want to make it dinamically. So, the main question is... How can I loop the data while constructing the object at the same time?
This is an example of the incoming object I work from:
[
{
"uid": 1,
"legendname": "item1",
"rows": [
{
"uid": 0,
"color": "482400",
"width": "482400",
"height": "25"
},
{
"uid": 1,
"color": "587898",
"width": "789658",
"height": "30"
}
]
}
{
"uid": 2,
"legendname": "item2",
"rows": [
{
"uid": 0,
"color": "482400",
"width": "482400",
"height": "25"
}
]
}
]
How can I loop the data while constructing the object at the same time?
Is not clear. But if you want to create a new structure based on the incoming one, you can use this:
// ar = your incoming object
// b_obj = your result
var b_obj = {}
for (var i = 0; i < ar.length; i++)
{
item = ar[i];
b_item = {};
for (var i_row = 0; i_row < item.rows.length; i_row++)
{
var row = {};
row.color = item.rows[i_row].color;
row.width = item.rows[i_row].width;
row.height = item.rows[i_row].height;
b_item[i_row] = row;
}
b_obj[item.legendname] = b_item;
}

Categories