Transform String Array into Object Array

Asked

Viewed 823 times

5

I got the following Array string:

["TagFuncao:CN Evento:TODOS", "TagFuncao:DOC.AGRO.INDUS Evento:TODOS"]

I need to transform this Array into an Object Array where TagFuncao and Evento is property of the Object, and CN and TODOS is the corresponding value of each property.

I did some tests on the browser console and arrived at the following result:

var newArr = r.map(i => {
var x = i.split(' ');
var p1 = x[0].replace('TagFuncao:','')
var p2 = x[1].replace('Evento:', '')
var obj = {
        tagFuncao: p1,
        evento: p2
    }

    return obj
})

Upshot:

[{tagFuncao: "CN", evento: "TODOS"}, {tagFuncao: "DOC.AGRO.INDUS", evento: "TODOS"}]

At first it solves my problem, but it doesn’t seem to be one of the best ways to do.

Question:

There are other ways to do this and achieve the same result that is not like this?

  • Note that this is not what you need, https://answall.com/questions/105978/converter-array--of-objects-para-um-array-de-arrays

4 answers

6


Follow a solution with regex

const array = [
  "TagFuncao:CN Evento:TODOS",
  "TagFuncao:DOC.AGRO.INDUS Evento:TODOS",
];

const nu_array = array.map((item) => {
  return { tagFuncao: item.match(/[^:]*\s/g)[0], evento: item.match(/[^:]*$/g)[0] };
});
  • Explanation

Select all items after : until next space

/[^:]*\s/g

Select all items after : until the end of the text

/[^:]*$/g

[0] is to take the first match item, because the function returns an array

  • Upshot
[ { tagFuncao: 'CN ', evento: 'TODOS' },
  { tagFuncao: 'DOC.AGRO.INDUS ', evento: 'TODOS' } ]
  • 2

    It turned out good. I had imagined doing two regex to analyze according to the Ecmascript standard but you proved me wrong.

  • 2

    @Augustovasques Remember that this solution works only if the strings have exactly Tagfuncao and Event in this order, and no other information. To accept more properties with different names (or only these two in another order, etc.), the other answers are better. As an improvement, I suggest changing * for +, so force to have at least one character (otherwise it will return empty string if the text ends with "Evento:")

  • @hkotsubo with the inclusion of the operator + generates an error in the function by taking the first value of the match [0] so, if no value comes it makes the value empty, I think it is a good solution to the problem. {..., evento : '' }

5

Assuming you always have a space between the values you want to read you can make a mapping with a reduce inside to extract these values.

A suggestion would be so:

const data = ["TagFuncao:CN Evento:TODOS", "TagFuncao:DOC.AGRO.INDUS Evento:TODOS"];

const objectificar = (string) => string.split(' ').reduce((obj, str) => {
    const [key, value] = str.split(':');
    return {
      ...obj,
      [key]: value
    }
  }, {});

const dataComObjetos = data.map(objectificar);
console.log(dataComObjetos);

3

It is not very different from what you did but has the advantage of not having to change the algorithm if you create a different key in the future:

let arr = [
  "TagFuncao:CN Evento:TODOS",
  "TagFuncao:DOC.AGRO.INDUS Evento:TODOS",
  "teste:-23 verdadeiro:false" //Chave de teste
];

//Função de conversão do texto para objeto, movi para fora do map para facilitar a leitura
function paraObjeto(texto) {
  let resultado = new Object(); //Cria um objeto vazio.
  propriedades = texto.split(' '); // Separa as propriedades pelo espaço entre elas.
  propriedades.forEach((item) => { //Para cada proriedade..
    chaveValor = item.split(':'); //Separa chave do valor
    resultado[chaveValor[0]] = chaveValor[1]; //Adiciona ao objeto a chave e seu respectivo valor
  });
  return resultado; //Retorna o objeto preenchido
}

let objetos = arr.map(item => paraObjeto(item));

console.log(objetos);

It was possible to adapt each string to the standard JSON to make the analysis with JSON.parse() but for the string to be analyzed each key pair/value would have to conform to the standard Ecmascript for identifiers and literal which would require two regular expressions whose construction effort would not be worth the result obtained.

1

There is no problem with your code, but I would suggest reducing the amount of variables created, if you use the variable only once, it probably doesn’t need to exist. Other than that, your code has the feature already commented not to be dynamic, if in the future the structure changes, the code will need to be changed, but this does not necessarily a problem, if you do not want to change its structure is so great

The best (in most cases) way to solve this is by changing the code that generates this array so that it uses a standardized format, such as JSON, CSV or similar. but if you don’t have access to this code or it’s too complicated to change it...

One solution is to turn the strings into valid Jsons and then do the parse. This is possible without the use of regular expressions:

var oldArray = [
  'TagFuncao:CN Evento:TODOS',
  'TagFuncao:DOC.AGRO.INDUS Evento:TODOS',
  'teste:-23 verdadeiro:false'
];

var json = oldArray.map(elements => `{"${elements.split(':').join('":"').split(' ').join('","')}"}`);

console.log(json);

var newArray = oldArray.map(elements => JSON.parse(`{"${elements.split(':').join('":"').split(' ').join('","')}"}`));

console.log(newArray);

  • 1

    I do not understand why they are negative. This answer to my view is good. Who gave the negative could please explain to me why you did not consider it useful?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.