Extract certain Columns and Rows from a json string - javascript

I get a JSON response like this from a server,
{
id : 1,
text : 'Name City Country \nJohn \n Chicago \nIllinois \nAlbert \nHouston \nTexas '
}
if I do console.log(response.text); the output is like this in tabular form
Now I want only want the Name column along with the rows and the output should look like this
Suggest me a workaround for this. Since the value is a string I'm facing a lot of trouble to extract only the required columns

I haven't tested this, but something like this should work:
var jsonData = "{ id : 1, text : 'Name City Country \nJohn \n Chicago \nIllinois \nAlbert \nHouston \nTexas ' }";
var obj1 = jsonData.split('\n');
for(var i= 1; i<obj1.length-2; i=i+3)
{
console.log("Name: " +obj1[i]+", City: "+obj1[i + 1]+", Country: " +obj1[i + 2]);
}

Use trim and split to get the Name City and Country texts.
const obj = { id : 1, text : 'Name City Country \nJohn \n Chicago \nIllinois \nAlbert \nHouston \nTexas ' }
console.log(obj.text.split("\n")[0].trim().split(" "));

You can use any of the javascript csv parser to parse the text to csv and access the particular column.
Ref: javascript-code-to-parse-csv-data

Related

How can i convert a text into an array of useful data?

I am extracting text from a server. The data I'm extracting is not organized for further use. The text I'm extracting looks like this:-
>>[Extracted] id: 194805284, got 55 points from jones (252906152669) date: 15/04/19 08:44:40 you have 30 points remaining
I don't want all this text I only want the id, points, number, and date.
Note: I might extract more than one of the message once in a while.
So to extract the id, points, number, and date, I wrapped every word with a span tag and then used this code:
var getData = {
//gets the id, points, date and number respectively
number1 : $('span:contains("id:")').next().text(),
amount : $('span:contains("got")').next().text(),
time : $('span:contains("date:")').next().text(),
number : $('span:contains("date:")').prev().text()
}
The reason I'm using this code is that I might extract automatically more than 1 message, so with every message that gets extracted, every word that it contains is the same except the id, points, date, and number.
I used the above code to extract the data I want, but this time there was 2 [extracted] messages, look below.
HTML
<p>[Extracted] id: 194805284, got 55 points from jones (252906152669)
date: 15/04/19 08:44:40 you have 30 points remanining [Extracted] id: 193537533, got 3 points from Micheal (907794804)
date: 14/04/19 10:15:32, you have 100 points remaining</p>
<div class="processed-data">
</div>
CSS:
span {
border: 1px solid red;
}
JS:
// wrap every word with <span> tag
var words = $("p").text().split(" ");
$("p").empty();
$.each(words, function(i, v) {
$("p").append($("<span>").text(v));
});
//extract the id, points, time and number respectively
var getData = {
number1: $('span:contains("id:")').next().text(),
amount: $('span:contains("got")').next().text(),
//amount : $('span:contains("got")').next().text().substring(1),
time: $('span:contains("date:")').next().text(),
number: $('span:contains("date:")').prev().text()
}
// Output the extracted data to .processed-data div
$('.processed-data').append("thisTime = { [id: " + getData.number1 + " amount: " + getData.amount + ", time: " + getData.time + " number: " + getData.number + "]}'");
Here's a JSFiddle
output:
thisTime = {[id: 194805284,193537533, amount: 553, time: 15/04/1914/04/19 number: (252906152669) (907794804) ]}'
The results I expect are:
For each [extracted] message to get its own array. By using a loop or anything else.
Example:
Now I'm getting this;
thisTime = {
[id: 194805284,193537533, // All the ids are stored in 1 array data
amount: 553, // All the points are stored in 1 array data e.t.c
time: 15/04/1914/04/19
number: (252906152669) (907794804)]
}
I want to get:
thisTime = {
[id: 194805284,
amount: 55,
time: 15/04/19
number: (252906152669)],
[id:193537533,
amount: 3,
time: 14/04/19
number: (907794804)]
}
I only want each message I extract to have its own array.
I suggest you use Regex to solve it, I think is better than Jquery method that you are using.
See a possible Regex solution:
var text = '[Extracted] id: 194805284, got 55 points from jones (252906152669) date: 15/04/19 08:44:40 you have 30 points remanining [Extracted] id: 193537533, got 3 points from Micheal (907794804) date: 14/04/19 10:15:32, you have 100 points remaining';
var textArray = text.split('[Extracted]');
var regularExpression = /id:\s+([0-9]+).+got\s+([0-9]+).+[^\(]+\(([0-9]+)\)\s+date:\s+([0-9\/\s:]+)/i;
var output = [];
var item;
for(var i = 1; i < textArray.length; i++){
item = textArray[i].match(regularExpression);
output.push({
id: item[1].trim(),
amount: item[2].trim(),
time: item[4].trim(),
number: item[3].trim()
});
}
console.log(output);
You could easily use a regular expression (Regex) to solve this -- is there any particular reason you're wrapping each word in a span?
The following regular expression should match all tokens in your string:
id:\s+(\d+),\s+got\s+(\d+)\s+points\s+from\s+.+?\s+\((\d+)\)\s+date:\s+(\d+)\/(\d+)\/(\d+)\s+(\d+):(\d+):(\d+)
I'm using \s+ here instead of spaces because it seems the spacing in your above template is inconsistent, and just to be safe I like to use \s+ for any whitespace of any quantity.
You can extract a message like so...
const regex = /id:\s+(\d+),\s+got\s+(\d+)\s+points\s+from\s+.+?\s+\((\d+)\)\s+date:\s+(\d+)\/(\d+)\/(\d+)\s+(\d+):(\d+):(\d+)/; // construct the regex literal
const message = // some string matching your "extracted" template
const match = message.match(regex); // now your match contains all the data
const [fullMatch, idString, pointString, dayString, monthString, yearString, hourString, minuteString, secondString] = match; // you don't have to destructure, but this is the order of the capturing groups.
You should also be able to match multiple as well, by doing the following...
let match;
while (match = regex.exec(message)) {
// now match can be handled the same way as above. You could alternatively push the matches to a list as well here.
}
Your issue is getData. I suggest to decompose the string splitting on Extracted and after on spaces. After, you can select sub spans grouping by sentences and filter in order to create an array containing one or more objects.
var sentences = $("p").text().split("\[Extracted\]").slice(1);
$("p").empty();
$.each(sentences, function(i, v) {
var words = ['Extracted'].concat(v.trim().split(/ +/));
$.each(words, function(idx, word) {
$("p").append($("<span/>", {text: word.trim()}));
});
});
var result = {thisTime: $("p span:contains(Extracted)").map(function(idx, txt) {
var x = $(this).nextUntil('span:contains(Extracted)');
return {id: x.filter('span:contains("id:")').next().text(),
amount: x.filter('span:contains("got")').next().text(),
time: x.filter('span:contains("date:")').next().text(),
number: x.filter('span:contains("date:")').prev().text()};
}).get()};
$('.processed-data').append(JSON.stringify(result));
span {
border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>[Extracted] id: 194805284, got 55 points from jones (252906152669)
date: 15/04/19 08:44:40 you have 30 points remanining [Extracted] id: 193537533, got 3 points from Micheal (907794804)
date: 14/04/19 10:15:32, you have 100 points remaining</p>
<div class="processed-data">
</div>

Extract information from string - JavaScript

I am currently implementing google places autocomplete and the module I am using in React Native gives me the address as a whole string and not in address components. However, I need to have the postal code and city separate. The example response always look like this:
address: 'Calle Gran Vía, 8, 28013 Madrid, Spain
From this string I would need to have an object that looks like this:
{
city: 'Madrid',
postal_code: 28013,
}
How could I achieve this?
It's not the most "clean" or "smooth" answer, but it's something:
var response = "address: 'Calle Gran Vía, 8, 28013 Madrid, Spain";
var subStr = response.split(",")[2];
var obj = {
city: subStr.split(" ")[2],
postal_code: subStr.split(" ")[1]
};
console.log(obj);
For the city I think the best way is to use an array of cities and search it in the string
var str = "Calle Gran Vía, 8, 28013 Madrid, Spain";
var cities = ["Paris", "Berlin", "Madrid"];
var city = cities.filter(function(item) {
if (str.search(item) != -1)
return item;
})[0] || null;
For the postal code you should use a regex depending on the country (a good list of regex by country)
Probably split the string by ',' with array methods, take the third element of the array and split that by ' ', then you have your data points.
If you can always count on it being in that same format, you can do the following.
var splitAdress = address.split(",");
//This will give you ["Calle Gran Vía", " 8", " 28013 Madrid", " Spain"]
splitAdress = splitAdress[2].split(" ");
//This will give you ["", "28013", "Madrid"]
You'll first split the string into an array based on the comma and then follow it up by splitting on the space. The extra element in the second array is due to the space. This is an example of what #CBroe pointed out in the comments.
list=adress.split(",")[2].split()
list[0] gives you the postal code
list[1] gives you the city name
It depend on if there is always a comma in the "Calle Gran Vía, 8", if not you can use instead list=adress.split(",")[-2].split()
You might want to try this.
var address="Calle Gran Vía, 8, 28013 Madrid, Spain";
var splits = address.split(',')[2].trim().split(' ');
var newAdd = {
city : splits[1],
postal_code : splits[0]
}
console.log(newAdd);

How to receive form elements and order them according to the MLA and APA format with js or php?

I want to put an add source section on my website. For this, I need to convert text type inputs as name, author, page, date, publisher into the MLA and APA format style. How can I do it?
I would just use the concatenation operator (+). Or, if you have ES6 features available, then I would use template strings.
Example for books (format: Last Name, First Name. Book Title. Publisher City: Publisher Name, Year Published. Medium.):
function convertToCitation() {
var lastName = yourForm.lastName.value;
var firstName = yourForm.firstName.value;
var bookTitle = yourForm.bookTitle.value;
var publisherCity = yourForm.publisherCity.value;
// ... repeat for all the other fields
return lastName + ', ' + firstName + '. ' + bookTitle + '. '
// ... repeat for all the other fields
// Or, if you have ES6 available...
return `${lastName}, ${firstName}. ${bookTitle}.....repeat for other fields`;
}

ignore commas within string in JSON when exporting to csv

I'm exporting json files to csv using Filesaver.js and json-export-excel.js. The comma separator is causing the columns to shift when it sees a comma in the string.
Plunker Demo
How can i ignore commas found within string?
<button ng-json-export-excel data="data" report-fields="{name: 'Name', quote: 'Quote'}" filename ="'famousQuote'" separator="," class="purple_btn btn">Export to Excel</button>
JS File:
$scope.data = [
{
name: "Jane Austen",
quote: "It isn\'t what we say or think that defines us, but what we do.",
},
{
name: "Stephen King",
quote: "Quiet people have the loudest minds.",
},
]
Current CSV output (Not Desired): (Note: | marks the columns in csv file)
Name Quote
Jane Austen | It isn't what we say or think that defines us| but what we do.|
Stephen King| Quiet people have the loudest minds. | |
Desired CSV output:
Name Quote
Jane Austen | It isn't what we say or think that defines us, but what we do.|
Stephen King| Quiet people have the loudest minds. |
For Excel, you need to wrap values in quotation marks. See this question.
In json-export-excel.js you'll see that the _objectToString method wraps the output in quotes but because the fieldValue variable isn't an object this is never called for this example.
function _objectToString(object) {
var output = '';
angular.forEach(object, function(value, key) {
output += key + ':' + value + ' ';
});
return '"' + output + '"';
}
var fieldValue = data !== null ? data : ' ';
if fieldValue !== undefined && angular.isObject(fieldValue)) {
fieldValue = _objectToString(fieldValue);
}
If you add an else statement to this to wrap the value in quotes, the CSV opens in Excel as desired.
} else if (typeof fieldValue === "string") {
fieldValue = '"' + fieldValue + '"';
}
Plunker

Parse text to json like using javascript (without jquery)

I have a text (pure text) that has values aligned to right, and field names (keys) aligned to left.
Key and Values have a single blank space Maximum for each, and any number of spaces separating them - minimum 2 spaces.
I need to get them to a tree so I can read those fields and extract values. I don't know how to proceed and parse this text (Example below) to the json like structure.
Example Text Input:
Item Name 1 value 1
Item Name 2 2
Third Item Long Name val 3
Fourth Item value 4
Desired output:
output = { 'ItemName1' : 'value 1',
'ItemName2' : '2',
'ThirdItemLongName' : 'val 3',
'FourthItem' : 'value 4' }
Edit:
I ended up using #Gueras Arnaud answer, with a small modification, becuase apparently my data has lots of blank spaces at the right.
var source = document.getElementById('source').value;
var newsource = "{" + source.replace(/(.+?)(?:\t+|\s{2,})(.+?)\n/g, '"$1":"$2",').replace(/,$/, '') + '}';
var jsonobjtree = JSON.parse(newsource);
for (var key in jsonobjtree) {
if (jsonobjtree.hasOwnProperty(key)) {
jsonobjtree[key] = jsonobjtree[key].replace(/^\s+|\s+$/g, '')
}
}
The best tool for that is regexp and the use of replace.
In this example, I try to match each line with this pattern :
/(.+?)(?:\t+|\s{2,})(.+?)\n
And insert the result to being like this : "key" : "value",
After I add { and } around the string result.
And to obtain an object I use JSON.parse()
var source = document.getElementById('source').value;
var newsource = "{" + source.replace(/(.+?)(?:\t+|\s{2,})(.+?)\n/g, '"$1":"$2",').replace(/,$/, '') + '}';
var obj = JSON.parse(newsource);
document.getElementById('source').value = newsource;
<textarea id="source" rows="10" cols="100">
Item Name 1 value 1
Item Name 2 2
Third Item Long Name val 3
Fourth Item value 4
</textarea>

Categories

Resources