csv to json, json key are incorrect - javascript

I have the following function
generateArrayFromCSV(data, delimiter = ',') {
const titles = data.slice(0, data.indexOf('\n')).split(delimiter);
return data
.slice(data.indexOf('\n') + 1)
.split('\n')
.map(v => {
const values = v.split(delimiter);
return titles.reduce(
(obj, title, index) => ((obj[title] = values[index]), obj),
{}
);
});
};
I input the following code (you need to JSON PARSE this )
generateArrayFromCSV(`"id","longitude","latitude","height","heading","pitch","roll"
"e33ccb1d-bd23-4da7-a006-caa3b998b5a0",139.60705614794117,35.713942413120606,20,0,0,0
"40ddec13-4888-48be-8382-6761b826f2f2",139.60697489329232,35.71356021532803,20,0,0,0
"396c841c-99a2-49ea-928f-dd26'`)
Now, it looks ok, when I load a csv into it, and get the returned value in the console, it looks correct.
The problem is, even if in the console my object appear like this
{"id": ""e33ccb1d-bd23-4da7-a006-caa3b998b5a0"", "longitude": "139.60705614794117", "latitude": "35.713942413120606"}
to actually access my object, I need to do the following
temp1["\"heading\""]
because there is actually those \"key\" everywhere
but I don't see a good way to remove them
I tried
(obj, title, index) => {title = title.replace('\"', ''); return ((obj[title] = values[index]), obj); },
but it remove only one \ (so it becomes like this)

Related

Remove last comma from JSON file in JS for consuption by Vue app

I'm consuming a JSON file using Axios in my Vue app. One of the fields (country)has a trailing comma and it's causing issues.
JSON
"country": "spain,france,"
....
"country": "spain,belgium,"
...
JS
I tried to replace a word using the code below and this worked fine. It replaced 'france' with 'XXXXXX'
const arr = this.countries;
const newArr = arr.map((countries) => {
if (countries === "france") {
return "XXXXXX";
}
// return countries;
});
console.log("commas " + newArr);
I have tried various ways to remove the end comma but I can't seem to work how to. Can anyone help with this, please?
From this point, where you have the "country" value from your XML for e.g. in the variable countryString you could do following:
let countryString = "belgium,france,";
let countries = countryString.split(",").filter(e => e).map((e) => {
if (e === "france") { return "XXXXXX"; }
return e;
});
console.log(countries);
You can use slice to remove last char:
let countryString = "belgium,france,";
countryString = countryString.slice(0, -1);
console.log(countryString)

Converting CSV to nested JSON in Javascript some data in multiple rows

I have a CSV file which needs to be converted into a Javascript object / JSON file. Doesn't really matter which since I'll be be handling the data in JS anyway and either is fine.
Data in csv:-
Name,Time,HeightOptions/WidthRange,HeightOptions/Options
EGBL,Today,12,12.13.14.15.16
,,26,12.13.14.15.16
Desired Output:-
{
Name:"EGBL",
Time:"Today",
HeightOptions : [
{WidthRange:"12",
Options:[12,13,14,15,16]},
{WidthRange:"26",
Options:[12,13,14,15,16]
}]
}
This is what I have came up with:
const CSV = (csv) => {
var attrs = csv.splice(0, 1);
console.log("attrsattrs", attrs);
var result = csv.map(function (row) {
var obj = {};
var rowData = row.split(",");
attrs[0].split(",").forEach(function (val, idx) {
obj = constructObj(val, obj, rowData[idx]);
});
return obj;
});
function constructObj(str, parentObj, data) {
if (str.split("/").length === 1) {
parentObj[str] = data;
return parentObj;
}
var curKey = str.split("/")[0];
if (!parentObj[curKey]) parentObj[curKey] = {};
parentObj[curKey] = constructObj(
str.split("/").slice(1).join("/"),
parentObj[curKey],
data
);
return parentObj;
}
console.log("resultresultresult", result);
};
But it returns like this:-
{
Name:"EGBL",
Time:"Today",
HeightOptions : [
{WidthRange:"12",
Options:"12.13.14.15.16"},
]
},{
Name:"",
Time:"",
HeightOptions : [
{WidthRange:"26",
Options:"12.13.14.15.16"
}]
}
So as you see code is reading through as rows and not combining in 1 object.
As far as possible I wish to have this done in vanilla JS without any other libraries.
Thanks folks.
Its the general way how the converter works. What you can do is, after getting the result in some JSON format, write another function that will convert to your final JSON format. Otherwise write your own CSV parser by reading it as raw text. Also you can play around by changing the csv format to different way so that you can get expected result (if possible).

How to store data retrieved from the server into an array with JavaScript?

Can someone tell me how can I store the values of the CSV file into an array that I am retrieving from the web server.
Data example:
Time2,Price,Size
0.0,20998.0,69
0.0,20999.0,18042
0.0,21001.0,14783
0.0,21003.0,100
Suppose I have the following scenario shown below:
var url1 = 'path for CSV file'
$.get(url1, function(data) {
// data param contains all the data that I retrieved from the csv
});
using the above example, how can I store my data into an array so the end result looks like the following:
A very straight forward approach:
Split into lines on \n
Split each line ,
const csv = `Time2,Price,Size
0.0,20998.0,69
0.0,20999.0,18042
0.0,21001.0,14783
0.0,21003.0,100`;
const result = csv.split("\n").map(l=>l.split(','));
console.log(result);
Use a reducer (Array.reduce):
// create an array of arrays
const csvLines = `Time2,Price,Size
0.0,20998.0,69
0.0,20999.0,18042
0.0,21001.0,14783
0.0,21003.0,100`
.split("\n")
.map(v => v.split(","));
// bonus: to array of objects
let headers = csvLines.shift();
const fromCsv = csvLines.reduce( (acc, val) => [...acc, {
[headers[0]]: parseFloat(val[0]),
[headers[1]]: parseFloat(val[1]),
[headers[2]]: parseFloat(val[2]) } ], []);
console.log(fromCsv);

Splitting a string for CSV formatting

I have a string that I've formed based on certain data. It contains a list of comma separated values.
I run this string through a function which allows me to separate these values so that I can show them appropriately in the HTML.
This works fine. However there's one error I'm unable to resolve. One of the returned values is from a HTML textfield which means the user can write on multiple different lines. As a result, the function I use to split up my values is splitting up the textfield values into multiple lines.
I've consoled logged my string before it hits the function. As you can see, the comments appear fine in the quotations with a space in between.
20,Order,Item,Title,,Assignee,Comments,Image Path,Timestamp,Due Date,Completed
21,0,1,"Issue 1",,"","I have some comments that are
going here on multiple lines",,"2019/11/28, 12:20:55","",""
The function
csvToJSON(csv) {
const lines: string[] = csv
// escape everything inside quotes to NOT remove the comma there
.replace(/"(.*?)"/gm, (item) => encodeURIComponent(item))
.split('\n');
lines.pop();
// separate the headers from the other lines and split them
const headers: string[] = lines.shift().split(',');
// should contain all CSV lines parsed for the html table
const data: any[] = lines.map((lineString, index) => {
const lineObj = {};
const lineValues = lineString.split(',');
headers.forEach((valueName, index) => {
// remove trailing spaces and quotes
if (lineValues[index] != undefined) {
lineObj[valueName] = lineValues[index].replace(/%22(.*?)%22/gm, (item) => decodeURIComponent(item)).trim();
}
});
return lineObj; // return lineObj for objects.
});
console.log('csvToJSON - data = ', data);
return { data, headers };
}
In the above function, you can see a console log at the end to log the final converted data.
This ends up resulting in the following:
0: {20: "21", Order: "0", Item: "1", Title: ""Issue 1"", "": "", Assignee: """", …}
1: {20: ""}
2: {20: "going here on multiple lines",,"2019/11/28", Order: "12:20:55","","""}
As you can see, my comments have been a bit butchered.
Is there a way to resolve this so that everything else is separated correctly, but my comments text (which can have multiple lines) isn't broken up?
try this method
function CSVtoArray(text) {
var re_valid = /^\s*(?:'[^'\\]*(?:\\[\S\s][^'\\]*)*'|"[^"\\]*(?:\\[\S\s][^"\\]*)*"|[^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)\s*(?:,\s*(?:'[^'\\]*(?:\\[\S\s][^'\\]*)*'|"[^"\\]*(?:\\[\S\s][^"\\]*)*"|[^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)\s*)*$/;
var re_value = /(?!\s*$)\s*(?:'([^'\\]*(?:\\[\S\s][^'\\]*)*)'|"([^"\\]*(?:\\[\S\s][^"\\]*)*)"|([^,'"\s\\]*(?:\s+[^,'"\s\\]+)*))\s*(?:,|$)/g;
if (!re_valid.test(text)) return null;
var a = [];
text.replace(re_value,
function(m0, m1, m2, m3) {
if (m1 !== undefined) a.push(m1.split("|");
else if (m2 !== undefined) a.push(m2.split(","));
else if (m3 !== undefined) a.push(m3);
return '';
});
if (/,\s*$/.test(text)) a.push('');
return a;
};

Javascript Node js search and return lines that contain a string in a file

I am new to javascript and struggling to come up with a solution. I have got a file that contains lines in JSON format. In the below code I have converted the JSON to objects and trimmed the white space on each line and returned the output.
Now, I need to not only remove the white spaces but to even search for a string(provided by the user and passed in as a variable) in each line of the file and if the string found it should return the entire line.
I tried .includes(req.params.msg) but couldn't get to right.
get(req, res) {
let arry = [];
const text = (fs.readFileSync('./pretty.out'));
arry = (text.toString().split('\n'));
let wat = [];
arry.forEach(i => {
if (!!i.trim()) {
wat.push(JSON.parse(i));
}
});
res.json(wat);
}
File's content will be,
{"foo" : "bar","bar" : "sit"}
{"foo" : "lorem","bar" : "ipsum"}
{"foo" : "dolor","bar" : "amet"}
If the user inputs sit then the output should be,
{"foo" : "bar","bar" : "sit"}
// using fs.readFileSync is fine, but only during process boot time
// if the data is dynamic you'll need to read it async
const data = (fs.readFileSync('./pretty.out'), 'utf8')
.split('\n')
.filter(line => line.trim())
.map(line => JSON.parse(line));
// input should use post requests
post(req, res) {
const query = req.body;
let results = data.filter(d => d.bar === query);
res.json(results);
}
Looks like you've got it in array format now, so this should work fine:
// To return multiple query matches:
function search(query){
return arr.filter(function(item){
return JSON.stringify(item).match(query) !== null;
})
}
// To return single (first) query match:
function search(query){
return arr.find(function(item){
return JSON.stringify(item).match(query) !== null;
})
}
If you're not converting it to an array of json object you can use:
function search(query){
return file.match(new RegExp("{.+"+query+".+}", "g"))
}
Here's a fiddle:
https://jsfiddle.net/1cqacj3b/11/ (modified to show results in html

Categories

Resources