Tengo la siguiente cadena:

person:juan&age:24&knowledge:html

El problema es que a veces la cadena es:

knowledge:html&person:juan&age:24

Y puede cambiar la posición de las claves y los valores.

En este caso, escribiría algo como esto:

const keys = ["person", "age", "knowledge"];
const keyAndValues = "person:juan&age:24&knowledge:html";

const result = [];

keys.forEach(key => {
  const indexKeyValues = keyAndValues.indexOf(key);
  if (indexKeyValues !== -1) {
    const lastCharIndex = keyAndValues.substring(indexKeyValues).indexOf("&");
    return keyAndValues.substring(indexKeyValues + key.length, lastCharIndex === -1 ? keyAndValues.substring(indexKeyValues).length - 1 || lastCharIndex);
  }
});

Pero no me gusta y sería genial si pudiera hacer algo como:

const resultsExpected = /regexGroupedRegardlessOfPosition/g.match("person:juan&age:24&knowledge:html");

console.log(resultsExpected); // { person: "juan", age: 24, knowledge: "html" }
4
juan garcia 26 feb. 2018 a las 20:47

5 respuestas

La mejor respuesta

Aquí hay una sola expresión para obtener el objeto:

const keyAndValues = "person:juan&age:24&knowledge:html";

const obj = Object.assign(...keyAndValues.split('&').map(s => s.split(':'))
                                         .map(([k, v]) => ({ [k]: v }))
);

console.log(obj);

Esto utiliza ES6 asignación de desestructuración, sintaxis de propagación y nombres de propiedades calculados.

3
trincot 26 feb. 2018 a las 18:05

Creo que una función simple que convertiría este tipo de cadena en un objeto puede ser una mejor solución. Mira este:

var keyAndValues = "person:juan&age:24&knowledge:html";

function weirdStringToObject(str){
    var obj = {};
    str.split('&').forEach(function(substr){
        var kv = substr.split(':');
        var key = kv[0];
        var value = kv[1] || null;
        obj[key] = value;
    });
    return obj;
}

console.log(weirdStringToObject(keyAndValues));

Requiere un poco de validación adicional, pero es fácil de seguir desde aquí.

1
Phiter 26 feb. 2018 a las 17:56
(knowledge|person|age):([^&]+)

Probablemente no quieras, pero aceptar cualquier clave:

(\w+):([^&]+)

https://regex101.com/r/HwW5I1/1/

2
zzxyz 26 feb. 2018 a las 18:25

Puede dividir la cadena y luego las partes y tomar la clave / valores de un objeto.

function getValues(string) {
    var object = {};
    
    string && string.split('&').forEach(p => {
        var [key, ...value] = p.split(':');
        object[key] = value.join(':');
    });
    return object;
}

console.log(getValues("knowledge:html&person:juan&age:24"));
console.log(getValues("foo:bar:baz&cool:space:aliens:survive"));
console.log(getValues(""));
3
Nina Scholz 26 feb. 2018 a las 18:40

Puedes hacer uso de:

Ejemplo de trabajo:

const str = "person:juan&age:24&knowledge:html";

let result = str.split("&").reduce((r, s) => {
  let i = s.indexOf(':');
  r[s.slice(0, i)] = s.slice(i + 1);
  return r;
}, {});

console.log(result);
1
Mohammad Usman 26 feb. 2018 a las 18:02