NodeJS - Convert CSV to JSON Object array - javascript

I'm trying to convert the below CSV formatted data into a JSON object array,
CSV formatted data: apples,oranges,grapes,peach,pineapple
JSON Object Array: {
fruits: [
{
"name": "apples"
},
{
"name": "oranges"
},
{
"name": "grapes"
},
{
"name": "peach"
},
{
"name": "pineapple"
}
]
}
I referred this npm package https://www.npmjs.com/package/csvtojson and this one with stream parser https://github.com/nicolashery/example-stream-parser, but not sure how this may fit with my need.
Can anyone please suggest a way to convert this CSV data to a JSON object array in the format that's been posted.
Solution for the above query (Please refer the below comments section for more details),
var res = {};
res.fruits = 'apples|1,oranges|2,grapes|3,peach|4,pineapple|5'
.split(',').map(function (fruit) { //as did by #Dmitriy Simushev in the below reply
return {
"name": fruit.split('|')[0],
"value": fruit.split('|')[1]
}
});
document.write('<pre>' + JSON.stringify(res, 0, 2) + '</pre>');

You can use plain javascript, with split and map functions
var res = {};
res.fruits = 'apples|1,oranges|2,grapes|3,peach|4,pineapple|5'
.split(',').map(e => ({
"name": e.split('|')[0],
"value": e.split('|')[1]
}));
document.write('<pre>' + JSON.stringify(res, 0, 2) + '</pre>');

var csv_data = 'apples,oranges,grapes,peach,pineapple';
var csv_array = csv_data.split(',');
var object = {};
var arr = [];
for(var i=0; i<csv_array.length; i++){
arr.push({name:csv_array[i]});
}
object['fruits'] = arr;
console.log(object);

You can easily combine String.prototype.split with Array.prototype.map to achieve the target.
Here is an example of how it could be done:
var data = "apples,oranges,grapes,peach,pineapple";
// Wrap fruits names with object,
var fruits = data.split(',').map(function(fruit) {
return {name: fruit}
});
// Wrap fruits set with outer object.
var json = {fruits: fruits};
// Show the result.
console.dir(json);

As shown in the docs, you can convert your csv file like this
var Converter = require("csvtojson").Converter;
var converter = new Converter({});
converter.fromFile("./yourCSVfile.csv", function(err, result){
// do something with "result", it's json
});

Every answer so far is not reflecting that your data is stored in a file. And I think this is what you are looking for. You can use simple Node.js streams to achieve this:
var fs = require('fs');
var es = require('event-stream');
fs.createReadStream('data.csv')
.pipe(es.split())
.on('data', (row) => {
console.log({
fruits: row.toString().split(',').map((fruit) => {
return {
name: fruit.trim()
}
})
});
});
You need to install event-stream npm install event-stream.

Related

how to create a map with unique keys from a parsed object in javascript es6/2015?

Lets say I receive a parsed json like below:
[{"a":1},{"a":2},{"a":3}]
The keys are the same which is a.
How do I make each a unique so that the map is usable?'
EDIT1:
Results I want:
let myMap = {}; //I declare my variable
//Then I fetch a json and parse it
fetch(link)
.then(function(response) {
return response.json(); //parse the json string
}).then(function(json) {
myMap = json; //set it to myMap to be used
}
For some reason I having duplicate keys although you guys said the json is unique. Do I have to set the json string to myMap first and then only parse it?
Basically you can use an Object as hash table
var data = [{ "a": 1 }, { "a": 2 }, { "a": 3 }],
object = Object.create(null);
data.forEach(function (el) {
object[el.a] = el;
});
console.log(object);
Or a Map
var data = [{ "a": 1 }, { "a": 2 }, { "a": 3 }],
map = new Map;
data.forEach(function (el) {
map.set(el.a, el);
});
console.log(map.get(1));
The advantage of Map over an Object is, the key can be anything. The key is not converted to string. Maps can have an object or other primitive or not primitive values as key.
Also if you have a single value list or want to make sure it IS unique you can use the index supplied like this:
obj.map((item, index) =>
...
)}
Maybe this?
[{a:1},{a:2},{a:3}].map(function(item, index) { item.id = index; return item; });
Map in javascript doesnot need a unique id, it will iterate through all the value. so it will iterate through all the objects irrespective the fact that the key is same
eg:
var kvArray = [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}]
var reformattedArray = kvArray.map(function(obj){
var rObj = {};
rObj[obj.key] = obj.value;
return rObj;
});
Well, [{a:1},{a:2},{a:3}] is already unique... but, It's an Array.
so you cannot access an object {a:2, ...} directly but find index with looping.
If I understand your question right way... you want to make new MAP with unique key a how about this way? - reduce can help us. :)
btw, Nina Scholz's answer is right.
let myMap = {}; //I declare my variable
//Then I fetch a json and parse it
fetch(link)
.then(function(response) {
return response.json(); //parse the json string
}).then(function(json) {
// myMap = json; //set it to myMap to be used
myMap = json.reduce(function(p, n) { p[n.a] = n; return p; }, {});
// n.a or n['a'] - primary key (in sample, [1,2,3...])
// "myMap[1].foo", "myMap[2].bar"
// or change KEY as your taste.
myMap = json.reduce(function(p, n) { p['k' + n.a] = n; return p; }, {});
// "myMap.k1.foo", "myMap.k2.bar"
// It's unique but if you want everything...
myMap = json.reduce(function(p, n) {
var k = 'k' + n.a;
if(p[k] !== undefined) { p[k] = n; }
else if(Array.isArray(p[k])) { p[k].push(n); }
else { p[k] = [p[k]] ; }
return p;
}, {});
}

High performance - converting Objects to Array while sorting keys

I have the following object:
var myObj = {
"4":{//The key is a number String.
id:4,name:aaaa
}
"1":{
id:1,name:a
}
"2":{
id:2,name:aa
}
"3":{
id:3,name:aaa
}
}
And i would like to convert it to the following array:
var myArr = [{id:1,name:a},{id:2,name:aa},{id:3,name:aaa},{id:4,name:aaaa}]
My question is more of a syntax question, can the following pseudo code be done with Javascript:
1. Create an array with the size of Object.keys(myObj).length.
2. For each key in myObj
2.1 set myArr[key] = myObj[key]
What would be the fastest way to achieve that?
BTW, it is used in my node.js server and not a browser client.
I don't think any manipulation will do any real performance gain.
Also, since JavaScript works on "reference to-" approach, the real hit here is to create an array and sort it, since you don't really deep-copy the objects.
it shouldn't be real performance hit since the array is small in your example.
in this case, prefer clear code over psudo-performant code:
var arr = [];
for (var o in myObj){
arr.push(myObj[o]);
}
arr.sort(function(a,b){
return a.id-b.id;
});
Just sort the keys:
var myObj = { "4": { id: 4, name: 'aaaa' }, "1": { id: 1, name: 'a' }, "2": { id: 2, name: 'aa' }, "3": { id: 3, name: 'aaa' } },
result = Object.keys(myObj).map(Number).sort(function (a, b) {
return a - b;
}).map(function (k) {
return myObj[k];
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
First of all your JSON is not a valid JSON, Use , and "". To achieve your task use Array.prototype.map
var myObj = {
"4":{//The key is a number String.
id:4,name:"aaaa"
},
"1":{
id:1,name:"a"
},
"2":{
id:2,name:"aa"
},
"3":{
id:3,name:"aaa"
}
};
var arr = Object.keys(myObj).sort(function(a,b){return +a - +b;}).map(function(x){ return myObj[x]; }); // ES6
document.write(JSON.stringify(arr));
For ECMAScript6 Use
var arr = Object.keys(myObj).sort().map( x => myObj[x]);
Using lodash:
var sortedById = _.sortBy(_.values(myObj), 'id');

How to convert serialize array value to JSON in javascript

i have serialize array like this
rate_3=26&rate_8=67&rate_12=98 etc..,
now i need to change this array as json type
{
"ID": "3",
"Rate": "26"
},
{
"ID": "8",
"Rate": "67"
},
{
"ID": "3",
"Rate": "26"
} ..,
etc
so i tried like this but its not working... please some one help me.
var o = {};
var a = table.$('input, select').serialize();
$.each(a, function()
{
if (o[this.name] !== undefined)
{
if (!o[this.name].push)
{
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
}
else
{
o[this.name] = this.value || '';
}
});
return o;
i m using datatable so i just need to get Datatables serialize array only for that used this line
var a = table.$('input, select').serialize();
even i tried with json2.js also but when i use json2.js it forcing the page to submit
var data_2 = JSON.stringify(block_form.serializeArray());
Simple method is to map over the results of a regex match, pushing new objects into the resulting array:
var out = str.match(/\d+=\d+/g).map(function (el) {
var arr = el.split('=');
return { id: arr[0], rate: arr[1] };
});
DEMO
Convert the output array to JSON with JSON.stringify(out).
If your data format is reliably in the rate_N=X& format, you can use simple string splitting to parse out the values. This appears to be similar to how query strings are formatted and, if that's the case, you shouldn't run into (m)any unusual entities.
First, you'll want to break each key-value pair apart (on the &). Then split each pair on the = to produce the key and value. You'll need to parse the ID out of the key (cut the rate_ off the front), which substr will work well for.
var data = "rate_3=26&rate_8=67&rate_12=98";
var pairs = data.split('&').reduce(function(collect, pair) {
var kv = pair.split('=');
var name = kv[0].substr(kv[0].indexOf('_') + 1);
collect.push({
id: name,
rate: kv[1]
});
return collect;
}, []);
document.getElementById('results').textContent = JSON.stringify(pairs);
<pre id="results"></pre>
http://jsfiddle.net/43hnftaf/
var str = 'rate_3=26&rate_8=67&rate_12=98'
var arr = str.split('&').map(function(element) {
return element.replace(/^rate_/, '');
}).map(function(element) {
var elements = element.split('=');
return {
"ID" : elements[0],
"Rate" : elements[1]
};
});
console.log(arr);

How can I filter an array to remove duplicate entries?

I have an array of data returned from my server. From this array I need to
get an array of Topics and an array of SubTopics:
var data =
[
{"topicId":1,"subTopicId":1,"topicName":"J","subTopicName":" Ar"},
{"topicId":1,"subTopicId":2,"topicName":"J","subTopicName":" Us"},
{"topicId":1,"subTopicId":3,"topicName":"J","subTopicName":" Ut"},
{"topicId":2,"subTopicId":4,"topicName":"L","subTopicName":" Ov"},
{"topicId":2,"subTopicId":5,"topicName":"L","subTopicName":" El"},
{"topicId":2,"subTopicId":6,"topicName":"L","subTopicName":" In"},
{"topicId":2,"subTopicId":7,"topicName":"L","subTopicName":" Pr"},
{"topicId":2,"subTopicId":8,"topicName":"L","subTopicName":" Va"},
{"topicId":2,"subTopicId":9,"topicName":"L","subTopicName":" Pa"}
]
I have code that I use to reformat this data and just give me topic information:
var topics = data.map(function (t) {
return {
id: t.topicId, name: t.topicName
};
});
But this gives me three entries for topicId 1 and six entries for topidId 2.
How I can filter out duplicate entries so I can for example the above would just give me a topic array of two entries. One for each topicId
Please no jQuery, lodash or other framework solutions as I didn't include these in the tags. thanks
This should work
topics = data.filter(function(item, index, data) {
for (var i = 0; i < data.length; i++) {
if (item.topicId === data[i].topicId) break;
}
return index === i;
}).map(function (item) {
return {
id: item.topicId,
name: item.topicName
};
});
If duplicate entries are equal, you can simplify filter function
data.filter(function(item, index, data) {
return data.indexOf(item) === index;
})
Here is the solution:
var data =
[
{"topicId":1,"subTopicId":1,"topicName":"J","subTopicName":" Ar"},
{"topicId":1,"subTopicId":2,"topicName":"J","subTopicName":" Us"},
{"topicId":1,"subTopicId":3,"topicName":"J","subTopicName":" Ut"},
{"topicId":2,"subTopicId":4,"topicName":"L","subTopicName":" Ov"},
{"topicId":2,"subTopicId":5,"topicName":"L","subTopicName":" El"},
{"topicId":2,"subTopicId":6,"topicName":"L","subTopicName":" In"},
{"topicId":2,"subTopicId":7,"topicName":"L","subTopicName":" Pr"},
{"topicId":2,"subTopicId":8,"topicName":"L","subTopicName":" Va"},
{"topicId":2,"subTopicId":9,"topicName":"L","subTopicName":" Pa"}
]
var arr = [],
collection = [];
$.each(data, function (index, value) {
if ($.inArray(value.topicId, arr) == -1) {
arr.push(value.topicId);
collection.push(value);
}
});
console.log(collection);
This will print the following into console:
Try this
var topicIds = {};
var unique = [];
topics.forEach(function(t){
if(!topicIds[t.id]){
unique.push(t);
topicIds[t.id] = true;
}
});
unique will have unique array of topics.
I suggest to use the smart library underscore.js http://underscorejs.org/
They implement functional behaviors like groupBy http://underscorejs.org/#groupBy
So you can simply use _.groupBy(data, function(t){return t.topicId;}) and you get grouped suptopics:
Object {1: Array[3], 2: Array[6]}
1: Array[3]
[{
subTopicId: 1
subTopicName: " Ar"
topicId: 1
topicName: "J"
},{
subTopicId: 2
subTopicName: " Us"
topicId: 1
topicName: "J"
}, ... ]

Parsing JSON to a regular JavaScript array

How can I load a regular array from a JSON Response like this:
{"project":"8","powerline":"188.396496","road":"7.876766","cost":"69885005.45"}
to
var cars = [8, 188.396496, 7.876766, 69885005.45];
I already tried something like this:
req.done(function(data) {
var cars = JSON.parse(data);
});
but it is not doing the job.
You can simply run a for..in loop like this. and keep pushing the values into a new array.
var obj = {
"project" : "8",
"powerline" : "188.396496",
"road" : "7.876766",
"cost" : "69885005.45"
}
var arr = [];
for (var key in obj) {
var val = parseFloat("0" + obj[key]);
arr.push(val)
}
You can manipulate JSON object as Array, please try this way
req.done(function(data) {
var cars = $.map(JSON.parse(data), function(value, index){
return i;
});
console.log(cars);
});
That's because you're getting an object when you're calling JSON.parse. You can run the following to get the values without keys:
req.done(function (data) {
var jsonData = JSON.parse(data),
cars = []
for (var key in jsonData) {
cars.push(jsonData[key])
}
})

Categories

Resources