Split a multidimensional javascript array - javascript

I have an array that looks something like this
[[1,2,3],[1,2,3]]
Because of the way it is being received (via ajax) it is being read as a string instead of an array
using .split(',') doesn't work here.
console.log shows it as [[1,2,3],[1,2,3]] so I know the data is going through, however if I were to put the array directly in the page it shows properly as array array
This is the ajax with the recommendation given below. It still comes as plaintext.
$.ajax({
url: "file.php" + "?param=" + param,
type: "POST",
data: 'data',
datatype: 'json',
success: function (data) {
object = JSON.parse(data);
filters();
}
})

Use JSON.parse() to convert from string to array:
var arr = JSON.parse('[[1,2,3],[1,2,3]]')
console.log(arr[0])

You can convert it to a multidimensional array by parsing it as a JSON string:
var parsedArray = JSON.parse(yourString);

Related

JavaScript - Coverting invalid object into json object

I am currently making an ajax call to return data from an API. The return value is an object of an array. This format is an invalid object so I am having issues accessing the data that is being returned to me.
How can I convert this object into a valid json object so I can access the data that is being returned?
Here is an example of the data being returned:
data = { ["<p>Retail Websites has a profit value of $243,291. In the year 2020 we have seen a growth rate of about 2.3% </p>" ] }
I've tried using dataType: json in my ajax call but the result value is still the same.
Here is my ajax call using "dataType: json" :
$.ajax({
type: "POST",
url: dataUrl,
data: {
"retailId": retailId,
},
dataType: "json",
async: true,
error: function () {
console.log("error")
}
}).done(function (data) {
console.log("retail data", data)
})
I am unable to access the data in this object. I am expecting to be able to access the data like a json object such as : data[0]. I am stuck on how to accomplish this.
If your data is set as:
var data = { ["<p>Retail Websites has a profit value of $243,291. In the year 2020 we have seen a growth rate of about 2.3% </p>" ] }
Then the problem is the curly braces with no key. When you remove them, the array is correct. data[0] is equal to the string you expect.
If the result of your API call is the whole of data = {...} and you know that it is, then you can capture the string, remove the characters at the beginning and end that don't belong (everything outside the square brackets) and use JSON.parse to get your JSON data. There are several ways to remove the characters. If the text is always the case, you can use substrings, or if you need to be more flexible, you can use regular expressions.

parsing json data without a comma separator

My JSON is like below
{"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}}
{"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}}
{"_id":1283378,"name":"Gorkhā","country":"NP","coord":{"lon":84.633331,"lat":28}}
{"_id":1270260,"name":"State of Haryāna","country":"IN","coord":{"lon":76,"lat":29}}
{"_id":708546,"name":"Holubynka","country":"UA","coord":{"lon":33.900002,"lat":44.599998}}
It is a JSON without comma separation, how to read this file? I tried to parse the JSON and add commas in between, but couldn't do that either.
myapp.controller('Ctrl', ['$scope', '$http', function($scope, $http) {
$http.get('todos.json').success(function(data) {
var nuarr = data.toString().split("\n");
for(i in nuarr) {
myjson.push(i+",");
}
});
}]);
This format is typically called "newline-delimited JSON" or "ndjson"; there are several modules that can parse this, but if you're data set is small and you can do it all at once, you're on the right track:
var ndjson = "..." // assuming your data is already loaded in as a string
var records = ndjson.split('\n').map(function (record) {
return JSON.parse(record)
})
That simplifies it a bit, but then you have all of your records in an array, as parsed JSON objects. What you do to them after that is up to you, but the key takeaway here is that your JSON is a list of objects, not a single object: you don't want to parse it as a whole, but as individual records.
Say then, you want to create an object whose keys are the individual IDs; that might be helpful:
var recordHash = {}
records.forEach(function (record) {
recordHash[record._id] = record
})
Now you can address the individual records as recordHash['12345678'] assuming that 12345678 is the id of the record you wanted. You'll want to mutate the records into whatever data structure makes sense for your application, so it really depends on what you're looking for, but that example might get you started.
I really don't recommend trying to mutate the data that you're receiving into some other format before parsing; it's fragile. You'll find it much safer and more re-usable to parse out the data in the way you were provided it, and then transform it into whatever data structure makes sense for your application.
$http.get expects that response must be json. You can write your own custom response transformer to do that so.
$http({
url: 'todos.json',
method: 'GET',
transformResponse: function (data) {
return data.split('\n').map(function(line) {
return JSON.parse(line);
});
}
}).success(function (response) {
console.log(response);
// do whatever you want to do
// response will be of type array of objects
});
Your JSON needs to be a single object or array. Just joining a bunch of objects together with a comma does not define a single JSON object. Try this instead to get a parsable array of objects:
var nuarr = data.toString().split("\n");
myjson = '[' + nuarr.join(',') + ']';
Then JSON.parse(myjson) should return an array of objects. Alternatively, you can just map each element of nuarr to it's JSON-parsed value and collect the results in another array.
$http.get expects that response must be json. You can write your own custom response transformer to do that so.
$http({
url: 'todos.json',
method: 'GET',
transformResponse: function (data) {
return data.split('\n').map(function(line) {
return JSON.parse(line);
});
}
}).success(function (response) {
console.log(response);
// do whatever you want to do
// response will be of type array of objects
});
var myJson = nuarr.join(',');
But what are you really trying to do? Your code is pushing the strings with a comma added into an array, so end up with
["{...},", "{...},", ...]
As I see it, You have a collection of json objects, with the delimiter as newline.
Try this:
myapp.controller('Ctrl', ['$scope', '$http', function($scope, $http) {
$http.get('todos.json').success(function(data) {
myjson = data.split("\n").map(function(line) { return JSON.parse(line); });
});
}]);
Use a regexp to split into lines, then map each line into its JSON-parsed equivalent, yielding an array of the objects on each line:
input . match(/^.*$/gm) . map(JSON.parse)
Or use split as other answers suggest:
input . split('\n') . map(JSON.parse)
As stupid as it may seem, we got tired of using commas and quotes with JSON, along with not having comments or multiline strings.
Knowing that Douglas Crockford and his disciples would cry 'Blasphemy', we proceeded to write a specification, parser, and formatter for our own Relaxed Json syntax.
The fact is you don't really need commas, and quotes are only needed in a few exceptional cases. And you don't need newlines either.
With Relaxed Json, to make your example work, you would just put '[' and ']' around what you already have and call
val realJson = parser.stringToJson(...)
But you don't need newlines between the array values.
And you can also remove all the commas in-between your key-values.
And you don't need quotes around your keys.
So you could do this:
[
{ _id:707860 name:Hurzuf country:UA
coord:{lon:34.283333 lat:44.549999}
}
{ _id:519188 name:Novinki country:RU
coord:{lon:37.666668 lat:55.683334}
}
]
Link To Specification:
http://www.relaxedjson.org
Link To NPM
https://www.npmjs.com/package/really-relaxed-json
Paste the example here to see how easy it is to parse:
http://www.relaxedjson.org/docs/converter.html
Update 2022
#milkandtang answer put me on the right path but JSON.parse() gave me trouble and returned errors even after splitting the lines. It keeps complaining about lines being empty or malformated.
This is what works for me with New-Line Delimited JSON
var ndjson = data;//must be a string
//declare variable that will be array of json
var json = [];
//split
ndjson.split('\n').map(function (record) {
//regex to format each array to a json object
var array = JSON.parse(`[${record.replace(/\}\n\{/g, '},{')}]`);
//push to json array
json.push(array);
})
//pheeew...
console.log(json);

How to cast JSON array values as integers in javascript (from php / mysql)

I have a php page which gets some data in mysql database and return a json file, and then I call this json file with an ajax call :
$.ajax({
type: "POST",
dataType: "json",
url: "get_players_stats.php", //Relative or absolute path to players_stats file
success: function(data) {
var list = [];
$.each(data, function() {
list.push([this.time, this.playersonline]);
})
console.log(list);
}
});
the console.log(list); shows me this :
[["-1009843200000", "1"], ["-252460800000", "2"], ["-94694400000", "3"], ["31536000000", "2"],....
but instead I want it to look like this :
[[-1009843200000, 1], [-252460800000, 2], [-94694400000, 3], [31536000000, 2],....
How can I do that ?
Could you just do something as simple as this?
$.each(data, function() {
list.push([Number(this.time), Number(this.playersonline)]);
}
Do you really need to convert those values to numeric ones? JavaScript only supports 53 bit integers, so parseInt('10765432100123456789') will be converted to 10765432100123458000 integer.
Working with large integers in JavaScript.
If you still would like to convert the response you can do something like this:
$.each(data, function() {
list.push([+this.time, +this.playersonline]);
})
This is a type conversion problem: your data is showing as text format and you want it as number format.
You could parse the text as float in javascript, but that would likely be very inefficient, when instead you could cast the data as the type you need in the SQL query that returns the JSON.
To get you more details on how, it would be good to see how you pull the data into the JSON in the first place.
EDIT:
the actual answer you should be using is here:
PHP json_encode encoding numbers as strings
ES6 syntax
http://jsbin.com/qamoru/edit?js,console
let arr=[["-1009843200000", "1"], ["-252460800000", "2"], ["-94694400000", "3"], ["31536000000", "2"]];
let newArr = arr.map((item)=> item.map((it)=> Number(it)));
console.log(newArr)
JS Bin on jsbin.com

Sorting Parsed Data with jQuery

I want to sort a list of clients (which is a list of keys from the variable “clients"), with a simple .sort().
I am unable to sort "clients", but I am able to sort "key_list" (they’re in alphabetical order in my console).
So...
What I'm seeing with document.write is a list of clients with "Client: (client_name)" with a line break after each client, which is good. But it's in no particular order.
What I'm seeing with console.log is an alphabetical list of clients, which is good. But there each client is not shown as "Client: (client_name)" and there is no line break. It's one large list, with each item separated by a comma.
Why am I unable to sort the keys in "clients"? Is it the way I'm trying to access the parsed "data"?
$.ajax ({
url: 'data.php?',
type: 'GET',
dataType: "json",
success: function(data) {
var clients = JSON.parse(data);
for (var key in clients) document.write('Client:' + ' ' + key + '<br>');
var key_list = Object.keys(clients);
console.log(key_list.sort(clients));
}
});
Because console.log() is only printing the key_list.sort(clients) object. So basically you are logging the object, not each element in the object.
So of course you are not getting the clients printed in the order you want in the document because you are doing that before you sort. Like Travis J said, you should use just .sort().
So you should do; console.log(clients.sort());
This will allow you to print the whole object and print out all the clients in sorted order.
EDIT:
$.ajax ({
url: 'data.php?',
type: 'GET',
dataType: "json",
success: function(data) {
var clients = JSON.parse(data);
var sortedClients = clients.sort();
for (var key in sortedClients){
document.write('Client:' + ' ' + key + '<br>');
console.log('Client: ' + key);
}
});
sort expects a callback function which takes two parameters, and also expects a return value based on a comparison between those two parameters.
.sort(function(a,b){ return a-b; });
You are sending sort an object from deserialized json, which is not a function that takes two parameters and returns a value based on comparison, so the sort does not work. By default, sort will use a lexicographical comparison.
This would be the default call
console.log(key_list.sort());

Separating values of JSON object

I'm new in using JSON and I have trouble extracting data from a parsed JSON object :
I have a getstats.php file that echoes a json encoded result from a mysql query. Here is an example of what the php file returns :
[{"x":"0","label":"July","y":"23"},{"x":"1","label":"August","y":"58"},{"x":"2","label":"September","y":"78"},{"x":"3","label":"October","y":"77"}]
This is caught by an ajax query in a separate javascript file :
$.ajax({
type: "POST",
url: "getstats.php",
dataType: "json",
data: {start : start, end : end},
success: function(data) {
//here I deal with the JSON
}
});
So far so good, I can access each values individually (data[2].month == 'September'...)
I want to split the variable data so I can use the values into a flot chart, so I need something like :
var dataset = [[0,23],[1,58],[2,78],[3,77]];
var xlabel = [[0,'July'],[1,'August'],[2,'September'],[3,'October']];
I can't figure out an easy way to do this (I mean without doing a loop through data and extracting the values into new arrays one by one).
Unless you restructure you JSON to represent the two arrays I don't see a different way. Whether you loop yourself or use a helper method from some library or your own code it will have to be traversed.
So that being said your data JSON could have two properties called PropA and PropB and those two properties would have exactly what you need for your dataset and xlabel arrays. So instead of looping through data you would just do:
dataset = data.PropA
xlabel= data.PropB

Categories