1

I am trying to do two things:

  1. Search a JSON file for a string ("TODO")
  2. Replace that string with the string that occurred previously ("Start Quiz")

So, all the TODO's have to be replaced by the string occurring in "englishDefault".

I have the following JSON:

{
  "semantics": [
    {
      "englishLabel": "Quiz introduction",
      "fields": [
        {
          "englishLabel": "Display introduction",
        },
        {
          "englishDefault": "Start Quiz",
          "default": "TODO"
        }
      ]
    }
  ]
}

Part 2 has been solved already, but I am having trouble extending the answer: Replace with previous string in a JSON array

1
  • 5
    The best way to handle this in JavaScript is to parse the JSON, work with the resulting object, and then serialize the object back to JSON. Anything else will involve fragile hacks. Commented Oct 17, 2016 at 12:12

5 Answers 5

2

Analyzing the input json structure, you are able to detect that the crucial array of objects is in fields property.
Use the following approach:

var jsonData = '{"semantics":[{"englishLabel":"Quiz introduction","fields":[{"englishLabel":"Display introduction"},{"englishDefault":"Start Quiz","default":"TODO"}]}]}';

jsonData = JSON.parse(jsonData);
jsonData['semantics'][0]['fields'].forEach(function(o){
    o['default'] && o['default'] === 'TODO' && (o['default'] = o['englishDefault']);
})

console.log(JSON.stringify(jsonData, 0, 4))

Sign up to request clarification or add additional context in comments.

Comments

1

You need a series of for loops here, from your example, it is not quite clear if TODO can appear anywhere in the JSON structures or just under the fields, so I will assume the simplest i.e. that it can only appear in the fields array

        for(var i = 0; i < semantics[0].fields.length; i++)
        {
          var fields = semantics[0].fields[i];

          //declare empty previous variable to store the previous key
          var previousKey;
          for (var key in fields) {

          if (p.hasOwnProperty(key)) {
            var value = fields[key];

           if(value == 'TODO')
           {
             console.log('Found TODO, please replace');
           }
           else {
             //If value was not TODO, then we save the present key to be used in the next iteration step as the previous key
             previousKey = key;
           } 
      }
    }
}

1 Comment

Thanks for the answer, is there a way to access the previous key value pair?
0

I read your previous question to better understand what you mean and I believe this is what you're looking for.

// Assign json to a variable so we can mutate it using JS
var data = {
  "semantics": [
    {
      "englishLabel": "Quiz introduction",
      "fields": [
        {
          "englishLabel": "Display introduction",
        },
        {
          "englishDefault": "Start Quiz",
          "default": "TODO"
        }
      ]
    }
  ]
};

// Loop over semantics and then fields to find the default values with TODO
// Replace by simply assigning the new value
data.semantics.forEach(function(semantic) {
    semantic.fields.forEach(function(field) {
        if (field.default === 'TODO')
            field.default = field.englishDefault;
    });
});

Comments

0

Can u try json stringify and replace method

var js_replace = {
  "semantics": [
    {
      "englishLabel": "Quiz introduction",
      "fields": [
        {
          "englishLabel": "Display introduction",
        },
        {
          "englishDefault": "Start Quiz",
          "default": "TODO"
        }
      ]
    }
  ]
};

var data= JSON.stringify(js_replace).replace(/TODO/g, '"REPLACETHIS"');
console.log(data);

Comments

0

I apologize for doing crazy indentation but it helps when I work in the console. JSON.stringify is (ab)used for its object walking. I grab the first sibling that doesn't have a value of 'TODO' when one of its siblings does... It is dificult to chose the one 'before' the 'todo' because it's a map not an array maps officially don't have a 'before' Don't do string manipulation though. This is the way you do it.

Please note that I am mutating the object that is passed to deToDoify, also note that this is general purpose and will deeply change any structure no matter where the 'TODO' value is.

const deToDoify = x =>
{ JSON.stringify
  (x,
    (k,v) =>
    { const keys = Object.keys( v )
      let toDude;
      const check = keys.some
      ( a=> ((v[a] == 'TODO') && (toDude=a,1) ))
      if ( check )
      { keys.some
        ( a => ((v[a] !== 'TODO') && (v[toDude] = v[a],1) )) }
      return v } )
   return x }

deToDoify(
  {
    "semantics": [
      {
        "englishLabel": "Quiz introduction",
        "fields": [
          {
            "englishLabel": "Display introduction",
          },
          {
            "englishDefault": "Start Quiz",
            "default": "TODO"
          }
        ]
      }
    ]
  })

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.