最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - parsing json data without a comma separator - Stack Overflow

programmeradmin3浏览0评论

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+",");
    }
  });
}]);

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+",");
    }
  });
}]);
Share Improve this question edited Mar 21, 2016 at 3:46 user663031 asked Mar 21, 2016 at 2:50 alexalex 1131 gold badge4 silver badges6 bronze badges 3
  • That's simply not JSON. – Phil Commented Mar 21, 2016 at 2:57
  • can you change your json as you want? if so, please wrap the data with "[" and "]" (without quote), and add "," at the end of each line (but not the last line). – s.xie Commented Mar 21, 2016 at 2:59
  • jq --slurp will convert this to a JSON array. – Brent Bradburn Commented May 10, 2023 at 22:45
Add a comment  | 

9 Answers 9

Reset to default 7

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.

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)

$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
});

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);
发布评论

评论列表(0)

  1. 暂无评论