Unfolding array of values into distinct categories - javascript

I have a JSON object(array) coming from a sharepoint table and I need to restructure the rows, but having a bit of a struggle (I'm fairly beginner in JS).
I have something like this:
[{'ID':'1', 'Title': 'First record', 'blue':'3', 'red':'6', 'yellow':'2'},
{'ID':'2', 'Title': 'Second record', 'blue':'1', 'red':'3', 'yellow':'6'}]
and I need to transform it into:
[{'ID':'1', 'Title': 'First record', 'category':'blue', 'count':'3'},
{'ID':'1', 'Title': 'First record', 'category':'red', 'count':'6'},
{'ID':'1', 'Title': 'First record', 'category':'yellow', 'count':'2'},
{'ID':'2', 'Title': 'Second record', 'category':'blue', 'count':'1'},
{'ID':'2', 'Title': 'Second record', 'category':'red', 'count':'3'},
{'ID':'2', 'Title': 'Second record', 'category':'yellow', 'count':'6'}]
What I'm trying to achieve:
Create separate rows to 'unlold' three category fields (blue, red, yellow), so one row becomes three
Preserve other fields in each newly created row (ID, Title)
I'm trying to reformat this data so that I can feed the array into Dimple/D3 chart to create a categorised chart showing value counts for each category.
I tried doing for...each and doing loops inside of loops and _.map from examples I've found, but not getting the output I'm after (debugging in browser is a pain, so not sure where the code fails for me :/ ). Would you be so kind as to show an example of how to do this manipulation properly (probably Underscore's .chain .each and .map)? Preferably without arrow functions (I need to make it work in IE11).
Thank you in advance!

It can be done by rebuilding new object collection; here is a sample;
var myData = JSON.parse('JsonString');
var transformedData = [];
myData.forEach(function(data){
transformedData.push({ ID: data.ID, Title: data.Title, category: "blue", count = data.blue });
transformedData.push({ ID: data.ID, Title: data.Title, category: "red", count = data.red });
transformedData.push({ ID: data.ID, Title: data.Title, category: "yellow", count = data.yellow });
});
var transformedJson = JSON.stringify(transformedData);
Remember JSON names should use double quotes " not single quotes '.

Related

Adding to a Multidimensional Array in Javascript

I have a multidimensional array that I am creating from a JSON Ajax call to my DB.
With in my Web App, I am trying to dynamically add a new row to the array using javascript along the lines of:
list[new_row_id].item_id = new_value ;
list[new_id].item_title = new_title ;
Clearly I am doing something wrong.
Any guidance would be appreciated.
Adding an element to the end of an array is done with the push-function:
array.push({"item_id": 10101, "item_title": "new title"});
If you meant "new_id" and "new_row_id" to be the same and it differs from an index starting from 0, because the keys are individual database keys, then you can solve it that way:
var any_db_id = 33;
var new_title = 'new title';
list[any_db_id] = {
item_id: any_db_id,
title: new_title
}
That will result in a JSON looking like that:
{
1: {
item_id: 1,
title: 'Entry coming from database 1'
},
5: {
item_id: 5,
title: 'Entry coming from database 2'
},
33: {
item_id: 33,
title: 'new title'
}
}
If the new_id and new_row_id are still same but it is actually just an index (each item has 0, 1, 2 and so on as key), then you should use the solution of Virendra Katariya.

How to search datatable using column name?

I am trying to search and filter data in datatable based on two columns.
Below is the code that I am using for search and redrawing the datatable.
(http://live.datatables.net/hapijuri/1/edit)
$(document).ready( function () {
var table = $('#example').DataTable({
"columns": [
{ title: 'title0', name: 'name0'},
{ title: 'title1', name: 'name1'},
{ title: 'title2', name: 'name2'},
{ title: 'title3', name: 'name3'},
{ title: 'title4', name: 'name4'},
{ title: 'title5', name: 'name5'},
]
});
table.column(1).search('Software Engineer')
.column(0).search('Bradley Greer').draw();
} );
The problem with this code is that it works on the column number (or index) and not on column name, however I have the column names on which I want to search.
Is there any way to search based on column name instead of index in datatables jquery?
Edit: Providing additional details to make sure I am able to present the question well.
So I have a datatable shown on UI and I am building a pivot table (using pivottable.js) in another tab using the datatable data.
On clicking the numbers in the pivot, I want the datatable data on the UI to be filtered so that it shows only those rows which are relevant to the number being clicked in pivot.
I am getting the column name and value corresponding to that number from pivot. I just need to search those column values in the datatable and show the filter the datatable accordingly.
As pointed in the example link that I shared, I am able to search through the data based on column index and the same is getting reflected on the UI.
What I am looking for is searching based on column name instead of column value.
For preventing a column being searched from table you have to add searchable:false. by default value of searchable & orderable is true.
var table = $('#example').DataTable({
"columns": [
{ title: 'title0', name: 'name0', "searchable": true},
{ title: 'title1', name: 'name1'},
{ title: 'title2', name: 'name2'},
{ title: 'title3', name: 'name3'},
{ title: 'title4', name: 'name4'},
{ title: 'title5', name: 'name5'},
]
});
no need to add below code unless you have server side data processing.
table.column(1).search('Software Engineer')
.column(0).search('Bradley Greer').draw();
Search a datatable using the column name
var table = $('#datatable-name').DataTable();
table.column('columnname:name').search("keyword").draw();

JSON error when calling chart.draw from Google GeoChart library

I'm trying to use Google GeoChart library to display a map, and if I do it on a local HTML file or somewhere like JSFiddle, it works perfectly.
However, when I embed it in a JSP on my project and deploy it (using JBoss), calling chart.draw results in a JSON error:
Invalid JSON string: {":",":",":{":[",","]},":",":{":true}}
My complete Javascript method is as follows:
var data2 = google.visualization.arrayToDataTable([
[{label: 'Country', type: 'string'},
{label: 'description', type: 'string'},
{label: 'consistency', type: 'number'},
{type: 'string', role: 'tooltip'}],
['Canada', "CANADA", 2, "OK"],
['France', "FRANCE", 0, "KO"],
['USA', "USA", 1, "Other"]
]);
var options = {
displayMode: 'region',
backgroundColor: '#81d4fa',
colorAxis: {
colors: ['red', 'orange', 'green']
},
legend: 'none',
tooltip: {
showColorCode: true
}
};
var chart = new google.visualization.GeoChart(document.getElementById('chart_div'));
chart.draw(data2, options);
So it's clearly picking up the "structure" of the JSON object (two simple objects, another object with an array inside, another simple object, another object with an array inside), but for some reason is not picking up the content, except for the 'true' value, so it looks like a problem with quotes...
In any case, I have tried simple and double quotes, removing the quotes from the identifiers, reducing the options object to a simple
var options = {
"legend": "none"
};
... but to no avail. Everything results in a Invalid JSON string error (in this last case, a Invalid JSON string: {":"} error, since there is only one object).
Last note: if I just use
var options = {};
it shows the map (but with the default options).
Any ideas as to why is this happening and/or how to solve it?
Thanks!

how to Dynamically generate JSON in a loop with Js?

I'm making a project with PebbleJS.
i'm a noob and i'm learning little by little..so after recieving a JSON from a webpage and put all the data in localStorage objects, i want to put my variables in a UI.Menu Window, which is basically a JSON variable as you can see in example below:
var main = new UI.Menu({
sections: [{
items: [
{
title: 'street name a',
subtitle: 'ID 1121'
}, {
title: 'street name b',
subtitle: 'ID 1431'
}, {
title: 'street name c',
subtitle: 'ID 1907'
},{
title: 'street name d',
subtitle: 'ID 1002'
},{
title: 'street name e',
subtitle: 'ID 1330'
},
]
}]
});
i tried to make a loop cycle inside but gives me error...(pseudocode)
for (var x=0;x<10;x++)
{
title: localStorage.title+x,
subtitle: 'ID '+localStorage.title+x
}
i need to make this with no jQuery or other JS Frameworks, only pure javascript...
if i understand you question correctly, you want to create the data-structure from your first code example through a loop.
the data structure is a object with some properties and sub-objects like arrays. the structure just defines objects in your code. there is no json involved.
json is a subset of javascript which is used to interchange data-structures. it consists of plain text files with just javascript object declarations and is usually parsed to create a data-structure in memory. by declaring your data-structure in code there is no need to use an additional json-parsing step.
to setup the initial structure as above you would do:
var data = {
sections: [
{
items: []
}
]
}
than you would get the items array:
var items = data.sections[0].items
to this array you can add the items with your loop:
for ( var x = 0; x < 10; x++ ) {
var item = {
title: localStorage.title + x,
subtitle: 'ID ' + localStorage.title + x
};
items.push(item);
}
now you can build your UI.Menu with the data-object.
var main = new UI.Menu(data)

Prevent Javascript function running out of memory because too many objects

I'm building a web scraper in nodeJS that uses request and cheerio to parse the DOM. While I am using node, I believe this is more of a general javascript question.
tl;dr - creating ~60,000 - 100,000 objects, uses up all my computer's RAM, get an out of memory error in node.
Here's how the scraper works. It's loops within loops, I've never designed anything this complex before so there might be way better ways to do this.
Loop 1: Creates 10 objects in array called 'sitesArr'. Each object represents one website to scrape.
var sitesArr = [
{
name: 'store name',
baseURL: 'www.basedomain.com',
categoryFunct: '(function(){ // do stuff })();',
gender: 'mens',
currency: 'USD',
title_selector: 'h1',
description_selector: 'p.description'
},
// ... x10
]
Loop 2: Loops through 'sitesArr'. For each site it goes to the homepage via 'request' and gets a list of category links, usually 30-70 URLs. Appends these URLs to the current 'sitesArr' object to which they belong, in an array property whose name is 'categories'.
var sitesArr = [
{
name: 'store name',
baseURL: 'www.basedomain.com',
categoryFunct: '(function(){ // do stuff })();',
gender: 'mens',
currency: 'USD',
title_selector: 'h1',
description_selector: 'p.description',
categories: [
{
name: 'shoes',
url: 'www.basedomain.com/shoes'
},{
name: 'socks',
url: 'www.basedomain.com/socks'
} // x 50
]
},
// ... x10
]
Loop 3: Loops through each 'category'. For each URL it gets a list of products links and puts them in an array. Usually ~300-1000 products per category
var sitesArr = [
{
name: 'store name',
baseURL: 'www.basedomain.com',
categoryFunct: '(function(){ // do stuff })();',
gender: 'mens',
currency: 'USD',
title_selector: 'h1',
description_selector: 'p.description',
categories: [
{
name: 'shoes',
url: 'www.basedomain.com/shoes',
products: [
'www.basedomain.com/shoes/product1.html',
'www.basedomain.com/shoes/product2.html',
'www.basedomain.com/shoes/product3.html',
// x 300
]
},// x 50
]
},
// ... x10
]
Loop 4: Loops through each of the 'products' array, goes to each URL and creates an object for each.
var product = {
infoLink: "www.basedomain.com/shoes/product1.html",
description: "This is a description for the object",
title: "Product 1",
Category: "Shoes",
imgs: ['http://foo.com/img.jpg','http://foo.com/img2.jpg','http://foo.com/img3.jpg'],
price: 60,
currency: 'USD'
}
Then, for each product object I'm shipping them off to a MongoDB function which does an upsert into my database
THE ISSUE
This all worked just fine, until the process got large. I'm creating about 60,000 product objects every time this script runs, and after a little while all of my computer's RAM is being used up. What's more, after getting about halfway through my process I get the following error in Node:
FATAL ERROR: CALL_AND_RETRY_2 Allocation failed - process out of memory
I'm very much of the mind that this is a code design issue. Should I be "deleting" the objects once I'm done with them? What's the best way to tackle this?

Categories