Tengo una cuerda como
string = "firstName:name1, lastName:last1";
ahora necesito un objeto obj tal que
obj = {firstName:name1, lastName:last1}
¿Cómo puedo hacer esto en JS?
Tengo una cuerda como
string = "firstName:name1, lastName:last1";
ahora necesito un objeto obj tal que
obj = {firstName:name1, lastName:last1}
¿Cómo puedo hacer esto en JS?
Respuestas:
En realidad, la mejor solución es usar JSON:
JSON.parse(text[, reviver]);
1)
var myobj = JSON.parse('{ "hello":"world" }');
alert(myobj.hello); // 'world'
2)
var myobj = JSON.parse(JSON.stringify({
hello: "world"
});
alert(myobj.hello); // 'world'
3) Pasar una función a JSON
var obj = {
hello: "World",
sayHello: (function() {
console.log("I say Hello!");
}).toString()
};
var myobj = JSON.parse(JSON.stringify(obj));
myobj.sayHello = new Function("return ("+myobj.sayHello+")")();
myobj.sayHello();
eval
más tarde.
Su cadena se ve como una cadena JSON sin las llaves.
Esto debería funcionar entonces:
obj = eval('({' + str + '})');
obj = eval('({' + str + '})');
Si estoy entendiendo correctamente:
var properties = string.split(', ');
var obj = {};
properties.forEach(function(property) {
var tup = property.split(':');
obj[tup[0]] = tup[1];
});
Supongo que el nombre de la propiedad está a la izquierda de los dos puntos y el valor de cadena que toma está a la derecha.
Tenga en cuenta que Array.forEach
es JavaScript 1.6: puede utilizar un kit de herramientas para obtener la máxima compatibilidad.
De esta manera simple ...
var string = "{firstName:'name1', lastName:'last1'}";
eval('var obj='+string);
alert(obj.firstName);
salida
name1
si estás usando JQuery:
var obj = jQuery.parseJSON('{"path":"/img/filename.jpg"}');
console.log(obj.path); // will print /img/filename.jpg
RECUERDE: eval es malvado! :RE
eval
. globalEval: /** code **/ window[ "eval" ].call( window, data ); /** more code **/
Dado que el método JSON.parse () requiere que las claves Object estén encerradas entre comillas para que funcione correctamente, primero tendríamos que convertir la cadena en una cadena con formato JSON antes de llamar al método JSON.parse ().
var obj = '{ firstName:"John", lastName:"Doe" }';
var jsonStr = obj.replace(/(\w+:)|(\w+ :)/g, function(matchedStr) {
return '"' + matchedStr.substring(0, matchedStr.length - 1) + '":';
});
obj = JSON.parse(jsonStr); //converts to a regular object
console.log(obj.firstName); // expected output: John
console.log(obj.lastName); // expected output: Doe
Esto funcionaría incluso si la cadena tiene un objeto complejo (como el siguiente) y todavía se convertiría correctamente. Solo asegúrate de que la cadena esté encerrada entre comillas simples.
var strObj = '{ name:"John Doe", age:33, favorites:{ sports:["hoops", "baseball"], movies:["star wars", "taxi driver"] }}';
var jsonStr = strObj.replace(/(\w+:)|(\w+ :)/g, function(s) {
return '"' + s.substring(0, s.length-1) + '":';
});
var obj = JSON.parse(jsonStr);
console.log(obj.favorites.movies[0]); // expected output: star wars
Necesita usar JSON.parse () para convertir String en un objeto:
var obj = JSON.parse('{ "firstName":"name1", "lastName": "last1" }');
Si tiene una cadena como foo: 1, bar: 2
puede convertirla en un obj válido con:
str
.split(',')
.map(x => x.split(':').map(y => y.trim()))
.reduce((a, x) => {
a[x[0]] = x[1];
return a;
}, {});
Gracias a niggler en #javascript por eso.
Actualización con explicaciones:
const obj = 'foo: 1, bar: 2'
.split(',') // split into ['foo: 1', 'bar: 2']
.map(keyVal => { // go over each keyVal value in that array
return keyVal
.split(':') // split into ['foo', '1'] and on the next loop ['bar', '2']
.map(_ => _.trim()) // loop over each value in each array and make sure it doesn't have trailing whitespace, the _ is irrelavent because i'm too lazy to think of a good var name for this
})
.reduce((accumulator, currentValue) => { // reduce() takes a func and a beginning object, we're making a fresh object
accumulator[currentValue[0]] = currentValue[1]
// accumulator starts at the beginning obj, in our case {}, and "accumulates" values to it
// since reduce() works like map() in the sense it iterates over an array, and it can be chained upon things like map(),
// first time through it would say "okay accumulator, accumulate currentValue[0] (which is 'foo') = currentValue[1] (which is '1')
// so first time reduce runs, it starts with empty object {} and assigns {foo: '1'} to it
// second time through, it "accumulates" {bar: '2'} to it. so now we have {foo: '1', bar: '2'}
return accumulator
}, {}) // when there are no more things in the array to iterate over, it returns the accumulated stuff
console.log(obj)
Documentos MDN confusos:
Demostración: http://jsbin.com/hiduhijevu/edit?js,console
Función:
const str2obj = str => {
return str
.split(',')
.map(keyVal => {
return keyVal
.split(':')
.map(_ => _.trim())
})
.reduce((accumulator, currentValue) => {
accumulator[currentValue[0]] = currentValue[1]
return accumulator
}, {})
}
console.log(str2obj('foo: 1, bar: 2')) // see? works!
Implementé una solución en unas pocas líneas de código que funciona de manera bastante confiable.
Tener un elemento HTML como este donde quiero pasar opciones personalizadas:
<div class="my-element"
data-options="background-color: #dadada; custom-key: custom-value;">
</div>
una función analiza las opciones personalizadas y devuelve un objeto para usarlo en alguna parte:
function readCustomOptions($elem){
var i, len, option, options, optionsObject = {};
options = $elem.data('options');
options = (options || '').replace(/\s/g,'').split(';');
for (i = 0, len = options.length - 1; i < len; i++){
option = options[i].split(':');
optionsObject[option[0]] = option[1];
}
return optionsObject;
}
console.log(readCustomOptions($('.my-element')));
data-
atributo en lugar de crear atributos pseudo-personalizados como algunos frameworks / bibliotecas.
string = "firstName:name1, lastName:last1";
Esto funcionará:
var fields = string.split(', '),
fieldObject = {};
if( typeof fields === 'object') ){
fields.each(function(field) {
var c = property.split(':');
fieldObject[c[0]] = c[1];
});
}
Sin embargo, no es eficiente. Qué sucede cuando tienes algo como esto:
string = "firstName:name1, lastName:last1, profileUrl:http://localhost/site/profile/1";
split()
dividirá 'http'. Así que te sugiero que uses un delimitador especial como tubería
string = "firstName|name1, lastName|last1";
var fields = string.split(', '),
fieldObject = {};
if( typeof fields === 'object') ){
fields.each(function(field) {
var c = property.split('|');
fieldObject[c[0]] = c[1];
});
}
Este es un código universal, no importa qué tan larga sea su entrada, sino en el mismo esquema si existe: separador :)
var string = "firstName:name1, lastName:last1";
var pass = string.replace(',',':');
var arr = pass.split(':');
var empty = {};
arr.forEach(function(el,i){
var b = i + 1, c = b/2, e = c.toString();
if(e.indexOf('.') != -1 ) {
empty[el] = arr[i+1];
}
});
console.log(empty)
Estoy usando JSON5 , y funciona bastante bien.
Lo bueno es que contiene no eval
y no new Function
, muy seguro de usar.
En tu caso
var KeyVal = string.split(", ");
var obj = {};
var i;
for (i in KeyVal) {
KeyVal[i] = KeyVal[i].split(":");
obj[eval(KeyVal[i][0])] = eval(KeyVal[i][1]);
}
var stringExample = "firstName:name1, lastName:last1 | firstName:name2, lastName:last2";
var initial_arr_objects = stringExample.split("|");
var objects =[];
initial_arr_objects.map((e) => {
var string = e;
var fields = string.split(','),fieldObject = {};
if( typeof fields === 'object') {
fields.forEach(function(field) {
var c = field.split(':');
fieldObject[c[0]] = c[1]; //use parseInt if integer wanted
});
}
console.log(fieldObject)
objects.push(fieldObject);
});
El conjunto de "objetos" tendrá todos los objetos
Sé que esta es una publicación antigua, pero no vi la respuesta correcta para la pregunta.
var jsonStrig = '{';
var items = string.split(',');
for (var i = 0; i < items.length; i++) {
var current = items[i].split(':');
jsonStrig += '"' + current[0] + '":"' + current[1] + '",';
}
jsonStrig = jsonStrig.substr(0, jsonStrig.length - 1);
jsonStrig += '}';
var obj = JSON.parse(jsonStrig);
console.log(obj.firstName, obj.lastName);
Ahora puede usar obj.firstName
y obj.lastName
para obtener los valores como lo haría normalmente con un objeto.