I have this object:
728394 : {
"playersAmount" : 2,
"players" : {
"LRFe9w9MQ6hf1urjAAAB" : {
"nickname" : "spieler1",
"type" : "player1"
},
"nKUDWEd5p_FCBO4sAAAD" : {
"nickname" : "spieler2",
"type" : "player2"
},
"ghdaWSWUdg27sf4sAAAC" : {
"nickname" : "spieler3",
"type" : "spectator"
}
},
"activePlayer" : "LRFe9w9MQ6hf1urjAAAB",
"board" : [
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]
]
}
How do I get everything of the object above except for the k/v pair "board"? is there any other way than just adding every key except the right one?
You can create a copy and then delete the unwanted key:
const copy = { ...original }
delete copy.unwantedProperty
Of course you can instead delete the property on the original if you don't care about mutating it.
(Note: if your environment doesn't support the syntax { ...original }, you can use Object.assign({}, original) instead.)
EDIT: Actually, this answer is even neater.
const { board, ...everythingButBoard } = yourObject
simple answer will be:
const copyObject = Object.assign({}, yourObject) // to make a copy of original variable
delete copyObject['keyToRemove'] // OR delete copyObject.keyToRemove
else if you want to delete from original variable:
delete yourObject['keyToRemove'] // OR delete yourObject.keyToRemove
I think you can create a new object excluding this key using a for...in
object = {
wantedKey: 'wantedValue',
wantedKey2: 'wantedValue2',
wantedKey3: 'wantedValue3',
unwantedKey: 'unwantedValue'
}
const newObject = {}
for (const key in object) {
if (key !== 'unwantedKey') newObject[key] = object[key]
}
console.log(newObject)
for more info about for...in: click here
I have an array objects that hold an id and a name
const stages = [{
id: 1,
name: ''
}, {
id: 2,
name: ''
}, {
id: 3,
name: ''
}, {
id: 4,
name: ''
}, {
id: 5,
name: ''
}, {
id: 6,
name: ''
}, {
id: 7,
name: ''
}, {
id: 8,
name: ''
}];
Further I have an array that holds numbers.
const indexPositions = [0, 1, 2, 2, 2, 3, 2, 0];
I want to create a third array that holds arrays. Each number in distances represents the index of the current array within the array.
If the current array does not exist yet I want to create it first. Obviously I have to create new arrays until I get to this index position.
Example:
My array is empty at start. The first index position is 0 so I have to create a new array for this. The next index position is 3 so I have to create more arrays until I have 4 arrays.
All I want to do is to push the stage to its correct level index position. The result of this example would be
const levels = [
[stage1, stage8],
[stage2],
[stage3, stage4, stage5, stage7],
[stage6]
];
Currently my code looks this
$(document).ready(() => {
const levels = []; // the array containing the arrays
stages.forEach((stage, stageIndex) => {
const indexPosition = indexPositions[stageIndex];
const positionDifference = indexPosition - levels.length;
if (positionDifference > 0) {
for (let i = 0; i < positionDifference; i++) { // fill up with empty arrays
levels.push([]);
}
}
levels[indexPosition].push(stage);
});
});
I get this error Uncaught TypeError: Cannot read property 'push' of undefined and this happens because the indexPosition is out of bounds. If the positionDifference is 0 no array gets created but in the beginning the array is empty.
I tried setting levels.length to -1 if it is 0 but I still get the error if the difference is 1, I create one array at position 0 and want to access position 1.
How can I create an empty array if it does not exist?
While I do not fully understand what you want to do, checking existence of an array element is simple, one way of doing that is coercing it to boolean:
const thing=[];
function addElem(where,what){
if(!thing[where]) // <- here
thing[where]=[];
thing[where].push(what);
}
addElem(2,1);
addElem(2,2);
addElem(2,3);
addElem(5,1);
console.log(thing);
(The indices are deliberately non-continuous, because that does not matter: JavaScript arrays are sparse)
You could use a single loop and add an array for the index if not exists. Then push the wanted value.
var stages = [{ id: 1, name: '' }, { id: 2, name: '' }, { id: 3, name: '' }, { id: 4, name: '' }, { id: 5, name: '' }, { id: 6, name: '' }, { id: 7, name: '' }, { id: 8, name: '' }],
indexPositions = [0, 1, 2, 2, 2, 3, 2, 0],
result = stages.reduce((r, o, i) => {
var index = indexPositions[i];
r[index] = r[index] || []; // take default value for falsy value
r[index].push('stage' + o.id); // instead of string take object
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You actually were very close! You have a very small issue in your code.
$(document).ready(() => {
const levels = []; // the array containing the arrays
stages.forEach((stage, stageIndex) => {
const indexPosition = indexPositions[stageIndex];
const positionDifference = indexPosition - levels.length + 1; //YOU DID NOT ADD 1 HERE
if (positionDifference > 0) {
for (let i = 0; i < positionDifference; i++) { // fill up with empty arrays
levels.push([]);
}
}
levels[indexPosition].push(stage);
});
});
When you were calculating the positionDifference, you did not add 1 causing the problem when indexPosition equaled 0 and the for loop did not run and no new arrays were pushed. Just adding one fixed the problem :-)
This i have to admin has always been my Achilles tendon despite my years of experience in programming.
I have a json result looking like this from which I want to draw a time series using highcharts.com
[{"iso-2":"DE","year":"2000","value":"0"},{"iso-2":"FR","year":"2000","value":"0"},{"iso-2":"KE","year":"2000","value":"0"},{"iso-2":"DE","year":"2001","value":"0"},{"iso-2":"FR","year":"2001","value":"0"},{"iso-2":"KE","year":"2001","value":"0"},{"iso-2":"DE","year":"2002","value":"0"},{"iso-2":"FR","year":"2002","value":"0"},{"iso-2":"KE","year":"2002","value":"0"},{"iso-2":"DE","year":"2003","value":"9355"},{"iso-2":"FR","year":"2003","value":"19490"},{"iso-2":"KE","year":"2003","value":"0"},{"iso-2":"DE","year":"2004","value":"0"},{"iso-2":"FR","year":"2004","value":"0"},{"iso-2":"KE","year":"2004","value":"0"},{"iso-2":"DE","year":"2005","value":"11"},{"iso-2":"FR","year":"2005","value":"8"},{"iso-2":"KE","year":"2005","value":"0"},{"iso-2":"DE","year":"2006","value":"2"},{"iso-2":"FR","year":"2006","value":"1388"},{"iso-2":"KE","year":"2006","value":"0"},{"iso-2":"DE","year":"2007","value":"0"},{"iso-2":"FR","year":"2007","value":"0"},{"iso-2":"KE","year":"2007","value":"0"}]
I'd like to dynamically generate the above result into an arrays that looks like this
series: [{
name: 'KE',
data: [0,0,0,0,0,0,0,0]
}, {
name: 'FR',
data: [0,0,0,19490,0,8,1388,0]
}, {
name: 'DE',
data: [0,0,0,9355,0,2,0]
}]
Thank you so much for looking into this
var gathered = data.reduce(function(prev, curr) {
if (prev.hasOwnProperty(curr["iso-2"])) {
prev[curr["iso-2"]].push(parseInt(curr["value"]));
} else {
prev[curr["iso-2"]] = [parseInt(curr["value"])];
}
return prev;
}, {});
var result = [];
for (var country in gathered) {
var obj = {};
obj["name"] = country;
obj["data"] = gathered[country];
result.push(obj);
}
console.log(result);
Output
[ { name: 'DE', data: [ 0, 0, 0, 9355, 0, 11, 2, 0 ] },
{ name: 'FR', data: [ 0, 0, 0, 19490, 0, 8, 1388, 0 ] },
{ name: 'KE', data: [ 0, 0, 0, 0, 0, 0, 0, 0 ] } ]
Here's what I can think of, considering the data you have in the JSON is sorted by year:
var json_data = '[{"iso-2":"DE","year":"2000","value":"0"},...]'; // This is the json data you have.
var data = JSON.parse(json_data); // Convert JSON data to javascript object or array
// Organize the data in an object
var organized = {};
data.forEach(function (item){
if (typeof organized[item['iso-2']] !== 'undefined'){
organized[item['iso-2']].push(item['value']);
} else {
organized[item['iso-2']] = [item['value']];
}
});
// Convert the object to the format you need
var series = [];
for (i in organized){
series.push({
name: i,
data: organized[i]
});
}
I'm consuming JSON data that has a bit of a weird structure for example:
{
"RESULT":
{
"COLUMNS": ["ID","name","ENABLED","perms","vcenabled","vcvalue","checkenabled","checkvalue","indxenabled","indxvalue"],
"DATA": [
[7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
[15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
]
},
"ERROR": 0
}
I would like to create some JavaScript that would restructure this data to proper JSON structures so that the "Column" array values become the keys for the "DATA" array's values. So after a JS process is run the data resembles the following:
[
{"ID":7,"name":"Site-A","ENABLED":1,"perms":"1,2","vcenabled":1,"vcvalue":1,"checkenabled":1,"checkvalue":1,"indxenabled":1,"indxvalue":1},
{"ID":15,"name":"Site-B","ENABLED":1,"perms":"1,2","vcenabled":1,"vcvalue":1,"checkenabled":1,"checkvalue":1,"indxenabled":1,"indxvalue":1}
]
What are the JavaScript best practices for accomplishing the JSON restructuring? Could I accomplish this task using a JS framework like JQuery, Foundation JS, ect... ?
Using Underscore, it's a one-liner:
var formatted = _.map(orig.RESULT.DATA, _.partial(_.object, orig.RESULT.COLUMNS));
With plain javascript (less elegant but faster), it would be
var formatted = [],
data = orig.RESULT.DATA,
cols = orig.RESULT.COLUMNS,
l = cols.length;
for (var i=0; i<data.length; i++) {
var d = data[i],
o = {};
for (var j=0; j<l; j++)
o[cols[j]] = d[j];
formatted.push(o);
}
newjson is your new object, j is your json,
code is very fast as it caches the legth and don't uses push.
And as it's pure javascript it's faster than all the libraries.
var j={
"RESULT":{
"COLUMNS":[
"ID",
"name",
"ENABLED",
"perms",
"vcenabled",
"vcvalue",
"checkenabled",
"checkvalue",
"indxenabled",
"indxvalue"
],
"DATA":[
[7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
[15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
]
},
"ERROR": 0
}
var newjson=[],d=j.RESULT.COLUMNS.length;
for(var a=0,b=j.RESULT.DATA.length;a<b;a++){
for(var c=0,tmpObj={};c<d;c++){
tmpObj[j.RESULT.COLUMNS[c]]=j.RESULT.DATA[a][c];
}
newjson[a]=tmpObj;
}
console.log(newjson);
based on Bergi's response u can also use the while-- loop.
var orig={
"RESULT":{
"COLUMNS":[
"ID",
"name",
"ENABLED",
"perms",
"vcenabled",
"vcvalue",
"checkenabled",
"checkvalue",
"indxenabled",
"indxvalue"
],
"DATA":[
[7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
[15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
]
},
"ERROR": 0
}
var formatted = [],
data = orig.RESULT.DATA,
cols = orig.RESULT.COLUMNS,
l = cols.length,
f = data.length;
while (f--) {
var d = data[f],
o = {},
g = l;
while (g--) {
o[cols[g]] = d[g];
}
formatted[f] = o;
}
you can use underscore Array functions for this task
http://underscorejs.org/#arrays
uusing the object function would be helpful
http://underscorejs.org/#object
from the documentation :
_.object(list, [values])
Converts arrays into objects. Pass either a single list of [key, value] pairs, or a list of keys, and a list of values ..the example:
_.object(['moe', 'larry', 'curly'], [30, 40, 50]);
=> {moe: 30, larry: 40, curly: 50}
here is the JSfiddle with the solution
http://jsfiddle.net/rayweb_on/kxR88/1/
and the code looks like this for this specific scenario.
var plain = {
"RESULT":
{
"COLUMNS": ["ID","name","ENABLED","perms","vcenabled","vcvalue","checkenabled","checkvalue","indxenabled","indxvalue"],
"DATA": [
[7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
[15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
]
},
"ERROR": 0
},
formatted = [];
_.each(plain.RESULT.DATA, function(value) {
var tmp = {};
tmp = _.object(plain.RESULT.COLUMNS,value)
formatted.push(tmp);
});
console.log(formatted);
Try this using underscorejs.
var plain = {
"RESULT":
{
"COLUMNS": ["ID","name","ENABLED","perms","vcenabled","vcvalue","checkenabled","checkvalue","indxenabled","indxvalue"],
"DATA": [
[7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
[15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
]
},
"ERROR": 0
}
, formatted = [];
_.each(plain.RESULT.DATA, function(value) {
var tmp = {};
_.each(value, function(parameter, pos) {
tmp[plain.RESULT.COLUMNS[pos]] = parameter;
});
formatted.push(tmp);
});
console.log(formatted);
http://jsfiddle.net/kxR88/
Actually, you could use a combination of Array#map for the array and Array#reduce for the objects with the new properties
var data = { RESULT: { COLUMNS: ["ID", "name", "ENABLED", "perms", "vcenabled", "vcvalue", "checkenabled", "checkvalue", "indxenabled", "indxvalue"], DATA: [[7, "Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0], [15, "Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]] }, ERROR: 0 },
result = data.RESULT.DATA.map(function (a) {
return a.reduce(function (o, d, i) {
o[data.RESULT.COLUMNS[i]] = d;
return o;
}, {});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
With ES6, you could use Object.assign with spread syntax ....
Object.assign adds properties to the given object and returns this object.
Spread syntax ... takes an array and insert the elements as parameters to the function.
var data = { RESULT: { COLUMNS: ["ID", "name", "ENABLED", "perms", "vcenabled", "vcvalue", "checkenabled", "checkvalue", "indxenabled", "indxvalue"], DATA: [[7, "Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0], [15, "Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]] }, ERROR: 0 },
result = data.RESULT.DATA.map(a =>
Object.assign(...data.RESULT.COLUMNS.map((k, i) => ({ [k]: a[i] }))));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using JQuery:
function jsonToObj(json){
return jQuery.parseJSON(JSON.stringify(json));
}
For example, after a GET request the server send a complex object
$.get("/Files/-2", function (rxData, status) {
var obj = jsonToObj(rxData);
console.log(obj);
});
Logged in console, can be explored through Chrome's Web Developer (F12), in my case looks like this:
image showing nested levels
By simple JS, your solution would look like this:
var yourObj = {
"RESULT": {
"COLUMNS": ["ID","name","ENABLED","perms","vcenabled","vcvalue","checkenabled","checkvalue","indxenabled","indxvalue"],
"DATA": [
[7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
[15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
]
},
"ERROR": 0
}
//Solution
var finalARR = [];
var colLength = yourObj.RESULT.COLUMNS.length;
var dataLength = yourObj.RESULT.DATA.length;
for (var i = 0; i < dataLength; i++) {
var finalJSON = {};
for (var j = 0; j < colLength; j++) {
finalJSON[yourObj.RESULT.COLUMNS[j]] = yourObj.RESULT.DATA[i][j];
}
finalARR[i] = finalJSON;
}
console.log(finalARR);
Here is the code:
//Note: x actually isn't defined, I'm pulling it from an external source
var x = [{ name: 'Michael Lovesllamas Lankford',
created: 1338420951.11,
laptop: 'pc',
laptop_version: null,
userid: '4fc6aed7eb35c14ad6000057',
acl: 0,
fans: 1,
points: 5,
avatarid: 34 }]
global.UserBase = {
userid: -1,
name: "noidea",
isSuperUser: false,
isDJ: false,
laptop: "pc",
afkWarned: false,
afkTime: Date.now(),
droppedTime: null,
droppedRoom: null,
songCount: 0,
mWaitingSongLimit: 0,
totalSongCount: 0,
totalHeartCount: 0,
totalHeartsGiven: 0,
customGreeting: null,
bootAfterSong: false,
joinedTime: Date.now(),
whiteList: false,
allowedToReserveSpot: true
};
global.mUsers = {length:0};
global.Register = function(a) {
for(var i = 0; i < a.length; i++) {
var sUser = a[i];
mUsers[sUser.userid] = CreateUser(sUser);
mUsers.length++;
}
};
global.CreateUser = function(a) {
var b = Object.create(UserBase);
b.userid = a.userid;
b.name = a.name;
b.laptop = a.laptop;
if (a.acl > 0) b.isSuperUser = true;
return b;
};
Register(x);
Now, to the problem. Instead of mUsers[sUser.userid] becoming this:
'4fc6aed7eb35c14ad6000057': {
userid: "4fc6aed7eb35c14ad6000057",
name: "noidea",
isSuperUser: false,
isDJ: false,
laptop: "pc",
afkWarned: false,
afkTime: Date.now(),
droppedTime: null,
droppedRoom: null,
songCount: 0,
mWaitingSongLimit: 0,
totalSongCount: 0,
totalHeartCount: 0,
totalHeartsGiven: 0,
customGreeting: null,
bootAfterSong: false,
joinedTime: Date.now(),
whiteList: false,
allowedToReserveSpot: true
}
it becomes this:
'4fc6aed7eb35c14ad6000057': {
userid: '4fc6aed7eb35c14ad6000057',
name: 'Michael Lovesllamas Lankford',
laptop: 'pc'
}
Any ideas why the rest of the values in UserBase aren't being added to the object?
Object.create creates a new object and sets its prototype to the object you pass in.
Your object is getting initialized, but you're only explicitly setting a few properties on the new object instance. The properties from the prototype object (UserBase) are all accessible, but a direct console.log of the object won't print them.
E.g. after running your code, doing:
for(var p in mUsers['4fc6aed7eb35c14ad6000057']) {
console.log(p, mUsers['4fc6aed7eb35c14ad6000057'][p]);
}
prints out:
userid 4fc6aed7eb35c14ad6000057
name Michael Lovesllamas Lankford
laptop pc
isSuperUser false
isDJ false
afkWarned false
afkTime 1340089066700
droppedTime null
droppedRoom null
songCount 0
mWaitingSongLimit 0
totalSongCount 0
totalHeartCount 0
totalHeartsGiven 0
customGreeting null
bootAfterSong false
joinedTime 1340089066700
whiteList false
allowedToReserveSpot true
UserBase is on global object, and you need to call Register on global object.
global.CreateUser = function(a) {
var b = Object.create(this.UserBase);
b.userid = a.userid;
b.name = a.name;
b.laptop = a.laptop;
if (a.acl > 0) b.isSuperUser = true;
return b;
};
global.Register(x);
this is happening beacause you are only initializing the values for
userid,
name and laptop.
see your code:
b.userid = a.userid;
b.name = a.name;
b.laptop = a.laptop;
to get the desired result, you need to call Global.Register(x) instead of Register(x)