Reorder a JSON collection - javascript

I have a JSON array fetch from my server which looks like :
[ {name: "Web Design", id: "27", month_n: "1", data: "68.00"},
{name: "Web Design", id: "27", month_n: "2", data: "56.00"} ,
{name: "Homework", id: "4", month_n: "2", data: "15.00"} ,
{name: "Gaming", id: "12", month_n: "2", data: "5.00"} ]
On the client side, I want to reorder this to have something similar to :
[{name: "Web Design", data:[68.00,56.00]}, {name:"Homework", data:[0,15]} and so on...
Where the "data" value is grouped by the "id" number and the month number (by default 0 if there's no month that match).
What's the best way ? I tried it the pure JavaScript way but I'm getting a hard time ! I have also heard It is easier with underscore JS. But don't know where to start.
Will someone please enlighten me ?

This can be done by two operations:
Groupby [name] field, then
Pluck [data] fields
There are pure JS array prototype extensions libraries to achieve this and many other operations with couple of lines. You may take a look at underscore.js. I have also written a simple JS library jsList. It comes with many unit-tests to use as example.
You only need to write these lines:
var arr = [ {name: "Web Design", id: "27", month_n: "1", data: "68.00"},
{name: "Web Design", id: "27", month_n: "2", data: "56.00"} ,
{name: "Homework", id: "4", month_n: "2", data: "15.00"} ,
{name: "Gaming", id: "12", month_n: "2", data: "5.00"} ];
var temp = arr.groupBy(function(item){ return item.name });
var result = [];
for(var key in temp){
result.push({name: key, data: temp[key].pluck('data')});
}
You may use Object.keys to avoid the for loop, but it only comes with Javascript 1.8.5 or later.
Thanks.

One way to do this in vanilla JavaScript, is to use a helper object as in the following code.
In a first step, we identify all distinct name values and group all data field by them.
In the second step, the helper object is converted back to an array.
var arr = [ {name: "Web Design", id: "27", month_n: "1", data: "68.00"},
{name: "Web Design", id: "27", month_n: "2", data: "56.00"} ,
{name: "Homework", id: "4", month_n: "2", data: "15.00"} ,
{name: "Gaming", id: "12", month_n: "2", data: "5.00"} ];
// use a helper object to identify all distinct "names"
var helper = {};
for( var i=arr.length; i--; ) {
// init an array, if it is not there
helper[ arr[i]['name'] ] = helper[ arr[i]['name'] ] || [];
// add the newest element
helper[ arr[i]['name'] ].push( helper[ arr[i]['data'] ] );
}
// convert back to an array
var newArr = [];
for( var key in helper ) {
if( helper.hasOwnProperty( key ) ) {
newArr.push( { 'name': key, 'data': helper[key] } );
}
}

Related

How to create Object with dynamic keys with value from string in pure js?

I'm trying to create an object with dynamic keys with key ID and value as a name from a string that I'm getting through API.
Below is my API
["PHP", "Project Management", "PHP dynamic website", "Ecommerce", "Magento", "Magento Websites"]
I want to convert it to following response
[
{ id: 0, name: "PHP" },
{ id: 1, name: "Project Management" },
{ id: 2, name: "PHP dynamic website" },
{ id: 3, name: "Ecommerce" }
]
You can map each name to an object which uses the index as the id and the value as the name property:
const arr = ["PHP", "Project Management", "PHP dynamic website", "Ecommerce", "Magento", "Magento Websites"];
const res = arr.map((name, id) => ({id, name}));
console.log(res);
Just use a forEach loop, and use the iterator as the key:
var apiResponse = ["PHP", "Project Management", "PHP dynamic website", "Ecommerce", "Magento", "Magento Websites"],
newResponse = [ ];
apiResponse.forEach(function(name, index) {
newResponse.push({ id: index, name: name });
});
console.log(newResponse);
Considering your usecase: Assuming newArr is the type of array you want
// ar is the initial array
ar=["PHP", "Project Management", "PHP dynamic website", "Ecommerce", "Magento", "Magento Websites"];
newArr=[];
for(i=0;i<ar.length;i++){
let obj={id:i,name:ar[i]};
newArr.push(obj);
}
console.log(newArr);
There no dynamic keys in here tho, all your objects and their keys look the same... Simply use the array.forEach() method to loop on all array values and push them into object into a new array:
let res = [];
sourceArr.forEach( (name, index) => {
res.push( {id: index, name: name} );
}
Easy as that.
I used traditional way. hope you are looking for this one.
B = ["PHP", "Project Management", "PHP dynamic website", "Ecommerce", "Magento", "Magento Websites"]
result = [];
for (i=0;i<B.length;i++)
{
result[i] = "{id:"+[i]+ "name:"+B[i]+"}";
}
console.log(result);

JSON Objects in a JSON Array in javascript

I am playing around with JSON objects in JSON arrays. On click of a button, I push the json objects into a array like below:
jsonArray.push({
columnNameProperty: columnName,
columnValueProerty: columnValue,
id: column.id
});
My resulted array looks like this:
[
0:{
columnNameProperty: "Name",
columnValueProperty: "Nancy",
id: "123"
},
1:{
columnNameProperty: "Name",
columnValueProperty: "Jene",
id: "124"
},
2:{
columnNameProperty: "Amount",
columnValueProperty: "1000",
id: "123"
},
3:{
columnNameProperty: "State",
columnValueProperty: "WA",
id: "123"
}
]
How do I modify this as I want to push items based on the id.
[
"123" : {
"Name" : "Nancy",
"Amount" : "1000",
"State" : "WA"
},
"124" : {
"Name" : "Jene"
}
]
Anyone could suggest me how to structure it in this format.
#Amy is correct, that is not in fact valid javascript. Arrays do not have keys. So your example
[
0:{
columnNameProperty: "Name",
columnValueProperty: "Nancy",
id: "123"
},
1:{
columnNameProperty: "Name",
columnValueProperty: "Jene",
id: "124"
}
]
really looks like this
[
{
columnNameProperty: "Name",
columnValueProperty: "Nancy",
id: "123"
},
{
columnNameProperty: "Name",
columnValueProperty: "Jene",
id: "124"
}
]
If your goal is to retrieve an element by id you could make a function that loops through the array, finds and returns the object with the given id.
Alternatively, you could create a hash map and access each values by its key. So for instance, given this object:
let map = {
"123" : {
"Name" : "Nancy",
"Amount" : "1000",
"State" : "WA"
},
"124" : {
"Name" : "Jene"
}
}
You could get the value of the key "123" by saying map['123']
Why do you have to use an array? For what you are trying to achieve you can set up a object and then just insert more objects into it.
var exampleObject={};
function onClick(){
exampleObject["123"]={"Name":"steve"}
}
I assume you are trying to use that approach to later find the right object in the array?
You can simply loop over the object and find it in there:
for (var obj in exampleObject){
if(obj==="123"){
//do something
}
}
Was able to achieve the required format by creating HashMap/Object:
var id = column.id;
var mapObject = {}, editMap = {};
if(editMap.hasOwnProperty(id)){
mapObject = editMap[id];
mapObject[columnName] = grid[columnName];
editMap[id] = mapObject;
}
else{
mapObject[columnName] = [columnName];
editMap[id] = mapObject;
}

Adding/removing items dynamically from JSON data parse from mySQL Database with Javascript

I have a mysql database with column ID, NAME , TYPE.
The database is then parsed in JSON structure as follows
[
{id: "1", name: "Snatch", type: "crime"},
{id: "2", name: "Witches of Eastwick", type: "comedy"},
{id: "3", name: "X-Men", type: "action"},
{id: "4", name: "Ordinary People", type: "drama"},
{id: "5", name: "Billy Elliot", type: "drama"},
{id: "6", name: "Toy Story", type: "children"}
]
If I want to add/remove item from the client side. How should I update it ?
I know I can use setInterval or setTimeout to refresh the table, but using this method will repopulate the table with the updated JSON object from the database.
Is there better ways to do it dynamically, with only the modified item getting updated ?
You can do it in 2 ways
1) Processing at client end.
Assume you keep the data in one variable as follows
var data = {your JSON} //Keep this variable only to identify the delta changes.
And when you submit your changes to the server just send only the delta changes.
var deltachanges = {
"added" = [
{id: "7", name: "Snatch V2", type: "crime"},
{id: "8", name: "Witches of Eastwick V2", type: "comedy"}],
"updated" = [
{id: "3", name: "X-Men - V3", type: "action"},
{id: "4", name: "Ordinary People -V4", type: "drama"}],
"deleted" = [
{id: "5", name: "Billy Elliot", type: "drama"}]
}
Now in your service just process this request with the above delta data and populate your data accordingly.
2) Processing at server side
Similar to client end processing, at the server side the delta changes has to be calculated, before it's persisted to database.

Rename variables at different levels of nested JSON dataset

I am looking to rename a variable with a different name depending on its level within a nested JSON dataset.
An example JSON file is the following:
[
{
key: "John Doe School",
values: [
{
key: "Mr. Brown",
values: [
{
key: "Joe",
TestScore: 95
},
{
key: "Sarah",
TestScore: 99
}
]
}
]
}
]
In this example, I would like to change the first-level "key" to "School", the second-level "key" to "Teacher", and the third-level "key" to "Student".
The JSON dataset would look like this following the changes:
[
{
School: "John Doe School",
values: [
{
Teacher: "Mr. Brown",
values: [
{
Student: "Joe",
TestScore: 95
},
{
Student: "Sarah",
TestScore: 99
}
]
}
]
}
]
Well, given your example, you could just do this...
var json = [
{
key: "John Doe School",
values: [
{
key: "Mr. Brown",
values: [
{
key: "Joe",
TestScore: 95
},
{
key: "Sarah",
TestScore: 99
}
]
}
]
}
];
json[0].key = "School";
json[0].values[0].key = "Teacher";
json[0].values[0].values[0].key = "Student";
json[0].values[0].values[1].key = "Student";
UPDATE FOLLOWING COMMENT
json[0]['School'] = json[0].key; // Add new key:value
delete json[0].key; // Delete previous one
json[0].values[0]['Teacher'] = json[0].values[0].key; // Add new key:value
delete json[0].values[0].key; // Delete previous one
json[0].values[0].values[0]['Student'] = json[0].values[0].values[0].key; // Add new key:value
delete json[0].values[0].values[0].key; // Delete previous one
json[0].values[0].values[1]['Student'] = json[0].values[0].values[1].key; // Add new key:value
delete json[0].values[0].values[1].key; // Delete previous one
I assume you will be looping through a number of different JSON objects however, so you would of course also need to implement that but the above structure should point you in the right direction ;)

How to reference data in array of hash in javascript: Windows 8 Metro

I've got some data stored this way:
var protossUnitsArray =
[
{ name: "Zealot", health:"100", shield:"50", armor:"1", picture: "/images/protoss/zealotPortrait.png" },
{ name: "Stalker", health: "80", shield: "80", armor: "1", picture: "/images/protoss/stalkerPortrait.png" },
{ name: "Sentry", health: "40", shield: "40", armor: "1", picture: "/images/protoss/sentryPortrait.png" },
{ name: "High Templar", health: "40", shield: "40", armor: "0", picture: "/images/protoss/hightemplarPortrait.png" },
{ name: "Dark Templar", health: "40", shield: "80", armor: "1", picture: "/images/protoss/darktemplarPortrait.png" },
{ name: "Immortal", health: "200", shield: "100", armor: "1", picture: "/images/protoss/immortalPortrait.png" }
];
var protossUnitsList = new WinJS.Binding.List(protossUnitsArray);
var publicMembers =
{
itemList: protossUnitsList
};
WinJS.Namespace.define("ProtossUnitsData", publicMembers);
As you can see, the array has been made publicly available.
How do I actually reference data from this array from another javascript file?
Let's say I want to know what a Stalker's health is (which is 80). Let's assume I know Stalkers are always going to be the second item in the array, shouldn't it be something like
ProtossUnitsData.itemList[1]['health'] ?
But that's not quite right..
If you want to access 2nd item from the array protossUnitsArray, shouldn't it be:
protossUnitsArray[1].health
I don't know about Windows 8 and the UI formerly known as Metro, but in JavaScript shouldn't it just be:
ProtossUnitsData.itemList[1].health
Edit
Looking at the documentation, it seems that WinJS.Binding.List exposes methods for working with the data in the List. See here and here for more info, but it looks like you want to use:
var item = ProtossUnitsData.getItem(1),
data = item.health;
That might work...
Figured it out! It's actually:
ProtossUnitsData.itemList.getAt(1).health;

Categories

Resources