0

alright? I have a function in js, that format some imperfections on Json values. Now this array must be higher, more data will be added, so I have many lines in the for loop. There is a form to assign replace to all itens in array using ES5 or ES6 using low lines of code?

for (var i = 0; i<data.length; i++) {
                data[i]['CotacaoBase'] = data[i]['CotacaoBase']
                .replace(",", ".")
                .replace("%", " ")
                .replace("R$", " ");                
                data[i]['DyMes'] = data[i]['DyMes']
                .replace(",", ".")
                .replace("%", "")
                .replace("R$", "");
                data[i]['pvp'] = data[i]['pvp']
                .replace(",", ".")
                .replace("%", " ")
                .replace("R$", "");
                data[i]['caixa_receber_12meses'] = data[i]['caixa_receber_12meses']
                .replace(",", ".")
                .replace("%", " ")
                .replace("R$", "");
                data[i]['caixa_receber_atual'] = data[i]['caixa_receber_atual']
                .replace(",", ".")
                .replace("%", " ")
                .replace("R$", "");
                data[i]['caixalivre_12meses'] = data[i]['caixalivre_12meses']
                .replace(",", ".")
                .replace("%", " ")
                .replace("R$", "");
                data[i]['caixalivre_hoje'] = data[i]['caixalivre_hoje']
                .replace(",", ".")
                .replace("%", " ")
                .replace("R$", "");
            }
j08691
  • 204,283
  • 31
  • 260
  • 272

5 Answers5

1

This is one way you could approach this problem.

Basically, in keysToFix, we are storing all the keys we want to fix.

Next in replaceMap, we are storing what character we want to replace and with what we want to replace.

Then, we are just looping through the above two items and fixing each element in data.

Now, if something new comes up, just add them to keysToFix and replaceMap.

const keysToFix = ['CotacaoBase', 'DyMes', 'pvp', 'caixa_receber_12meses', 'caixa_receber_atual', 'caixalivre_12meses', 'caixalivre_hoje'];

const replaceMap = {
  ",": ".",
  "%": " ",
  "R$": " "
};

for (var i = 0; i < data.length; i++) {
    for (key of keysToFix) {
        for (itemToReplace in replaceMap) {
            data[i][key] = data[i][key].replace(itemToReplace, replaceMap[itemToReplace];
        }
    }
}
Nisanth Reddy
  • 5,967
  • 1
  • 11
  • 29
0

Store the values like 'CotacaoBase' 'DyMes' in an array and try to iterate over it.

Naveenkumar M
  • 616
  • 3
  • 17
0

Knowing the exact keys

If you look at your code, you can see 7 very similar pieces of code. The only difference is string used. For each occurance, you can write

 data[i][s] = data[i][s]
                .replace(",", ".")
                .replace("%", " ")
                .replace("R$", " "); 

where s is one of the seven strings: CotacaoBase, DyMes, etc. And this is exactly the definition of when you should use a loop in your code: a block of instructions is repeated several times for slightly different parameters.

So let's collect all these strings in an array.

const strings = ['CotacaoBase', 'DyMes', ..., 'caixalivre_hoje']

Now let's iterate over it. There are many ways to do it; one of them is a C-like index-based for-loop.

for (let si = 0; si < strings.length; si++) {
  const s = strings[si]
  data[i][s] = data[i][s]
                .replace(",", ".")
                .replace("%", " ")
                .replace("R$", " "); 
}

Note that si is a number where the index of an element is stored, so we need to grab the actual string by doing s = strings[si] firstly.

There are other ways to iterate as well, which are arguably easier to understand. We don't need the index si at all in the end (we just used it to grab the s). So we can use for-of loop which allows us to skip this step entirely.

for (const s of strings) {
  data[i][s] = data[i][s]
                .replace(",", ".")
                .replace("%", " ")
                .replace("R$", " "); 
}

Notice that only the first two lines changed in this snippet and the previous one.

You could also use the forEach method that's available for every Array in JavaScript.

strings.forEach(s => {
  data[i][s] = data[i][s]
                .replace(",", ".")
                .replace("%", " ")
                .replace("R$", " "); 
})

Keys are unknown

If the keys in your object are unknown, and you want to do the replacement for every single s, no matter what it is, you can use the Object.keys function. It will return the array of strings used as keys.

const object = { a: 1, b: 2 }
const strings = Object.keys(object)
// strings: ['a', 'b']

So instead of defining

const strings = ['CotacaoBase', 'DyMes', ..., 'caixalivre_hoje']

yourself, you can do

const strings = Object.keys(data[i])

and then proceed as I've previously explained.


A slight off-topic clarification about your question: JSON has little to do with this question. You're working with a JavaScript array, stored in a variable data. How exactly this object is stored in memory is of little concern to you at the moment, but it's certainly not stored as a JSON string. Maybe you based this data of a JSON string you received from the server, but you're no longer using it. "JSON" is not "a JavaScript object", and many confusions stem from it.

Lazar Ljubenović
  • 18,976
  • 10
  • 56
  • 91
0

Maybe this will work.

 for(var i = 0; i < data.length; i++) {
  for(var prop in data[i])
    data[i][prop] = data[i][prop].replace(',', '.').replace('%', '.').replace('R$', '.');
}
pullidea-dev
  • 1,768
  • 1
  • 7
  • 23
0

If you have access to the "raw" JSON string before it gets parsed to POJO ("Plain Old JavaScript Object", in your case array), I'd advise using JSON.parse Reviver parameter.

It is meant exactly for this usage: it is called during parsing on each key-value pair and allows you to modify the value to your liking:

// parse JSON and get "amount" values cleaned
var data = JSON.parse(
  `[ { "fix this": "1,2%R$" },
     { "not this": "a,b%R$" }
   ]
  `,
  cleanAmountValues // ← "reviver" function
);

function cleanAmountValues(key, value) {
  // using RegExp, just to simplify this example
  // you can use any kind of test of value or key
  var pattern = /^([0-9]*),([0-9]*)\%R\$$/;
  var replacement = '$1.$2';
  if (typeof value == 'string' && pattern.test(value)) {
    return value.replace(pattern, replacement);
  } else {
    return value
  }
};

console.log(
  'Result:', JSON.stringify(data, null, '\t'));

This example changes string values of specific format during the parse step, what is presumably quite real-world usage. It makes no assumptions about data and does not even look at keys. So resulting data array has such values cleaned without need to iterate and amend this array again.

Super straightforward variation that blindly replaces commas to dots and percents and 'R$' to spaces in all values would be:


console.log( 
  JSON.parse(
    `[{"a":"░,░%░R$░"}]`,
    function(key,value) {
      return typeof value == 'string'
      ? value.replace(',','.').replace(/%|R\$/g,' ')
      : value
    }
  )
)

You can even exploit visitor function when you already have POJO: you can convert it back to JSON string and parse it back with visitor (JSON.parse(JSON.stringify(data),visitor)), but it would probably not scale well and you'd better work with array directly as advised in other answers.

myf
  • 9,874
  • 2
  • 37
  • 49