1

I'm aware that object's properties are not guaranteed to be stored or read in any particular order.

The problem I have is that it's not up to me to use an object or an array. I already have a big and very nested JSON file like this:

{ "occasion": 23, "mayorstips": { "1": 0, "3": 0, "2": 0...

I only have to do some modifications. This is how I start working with it:

var campaign = JSON.parse(fs.readFileSync(theJSONFile));
for(var plot in plots) {
    if(plots.hasOwnProperty(plot)) {
        switch(plots[plot].province) {
            case 'forest':
               ...

When I'm done, I just put it back with:

fs.writeFileSync(theJSONFile, JSON.stringify(campaign));

Now, I've noticed two problems with this approach:

  1. The original spacing format is lost. That original file is just one long line and needs to be one long line so any formatting attempt by the JSON library hasn't been helpful. I solved it with a few regex replacements.
  2. Now the "JSON line" file is sorted. So I went from { "1": 0, "3": 0, "2": 0 to { "1": 0, "2": 0, "3": 0 and that turns out to be a big problem.
  3. The float numbers that end in 0's are truncated. This file needs the float numbers to always have six decimals, for example, 34.293800. But when I open it, the number changes to 34.2938!

It's a 35 thousand chars line. It's How can I fix problem #2 and #3? I could do yet another regex replace for #3 but maybe there's something I'm missing.

Carles Alcolea
  • 7,984
  • 4
  • 30
  • 51
  • 1
    The json file you are reading, is it created by you or you are getting from somewhere? If it is created by you I strongly recommend changing its structure. If anywhere order matters to you, better keep those in array rather than object properties. If 0's matter to you, keep those numbers in strings – shinobi Jul 14 '16 at 07:05
  • 1
    It says that it isnt up to him. The only option i see is to push the data into an array to keep the order and then convert it back. this cant be done purely with JSON since each JS engine sorts it differently . http://stackoverflow.com/questions/8931967/how-to-deterministically-verify-that-a-json-object-hasnt-been-modified – JSB Jul 14 '16 at 07:10
  • 1
    For such a restricted use-case, I would suggest string manipulation, Do a substring search and find the key and its value. Then replace/manipulate the string. Though this approach is inefficient, considering your restrictions...... – Nidhin David Jul 14 '16 at 09:11
  • @shinobi It is not created by me, that's the problem. It's the output of a software I'm trying to modify to my preferences and it seems to be very picky about sorting and all that other stuff. – Carles Alcolea Jul 14 '16 at 10:19
  • @NidhinDavid I'm afraid you are right and it's actually half the code I have right now with regex replacements. I'm just fishing for that brilliant idea I just don't have. – Carles Alcolea Jul 14 '16 at 10:20
  • If there is something magic about your "JSON" file that insists on properties being in a a particular order, or numbers being in a particular format, then it is not JSON, since JSON is a well-defined standard that explicitly states that neither of those things matters. So call it "XSON" instead. If you want to process XSON, then you will need to write your own XSON parser and stringifier. Or, preferably, have a discussion with the person or system that is creating this XSON and get them to switch to JSON. The future will thank you. –  Jul 14 '16 at 10:43

1 Answers1

1

Looking at the question and comments, String manipulation it is. I don't exactly know what you want to do with the data, but, in case json makes your data processing easy, you can do a combination of both.

  1. Lets say you read it as string and at this point using regex you store the order of 1,3,2 in { "1": 0, "3": 0, "2": 0... in an array, also add quotes around the numbers you need to maintain the 0's.
  2. Now convert this string to json.
  3. Process your data
  4. convert json back to string (while converting your array you created in step 1 back to required format { "1": 0, "3": 0, "2": 0... in string)

Also have a look at this issue How to keep an Javascript object/array ordered while also maintaining key lookups?

Hope that helps. All the best!

Community
  • 1
  • 1
shinobi
  • 2,281
  • 1
  • 16
  • 25
  • I'm progressing with string manipulation, basically pure regex. Regarding your answer, the parse/stringify methodology is what screws up the order... unless I understood you correctly, it would have the same problem. – Carles Alcolea Jul 14 '16 at 12:47
  • Yeah, but i was asking you to read that as a text file first, then from that text(string) first store the order somewhere in an array. Then you parse it into json. Although now you will have the order changed, you still have the correct order in your array. So when stringifying back, you will pick the order from your array. Hope that was clear. – shinobi Jul 14 '16 at 13:08