J'ai une ficelle comme
string = "firstName:name1, lastName:last1";
maintenant j'ai besoin d'un objet obj tel que
obj = {firstName:name1, lastName:last1}
Comment puis-je faire cela dans JS?
En fait, la meilleure solution consiste à utiliser 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) Passer une fonction à 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();
Votre chaîne ressemble à une chaîne JSON sans les accolades.
Cela devrait fonctionner alors:
obj = eval('({' + str + '})');
Si je comprends bien:
var properties = string.split(', ');
var obj = {};
properties.forEach(function(property) {
var tup = property.split(':');
obj[tup[0]] = tup[1];
});
Je suppose que le nom de la propriété est à gauche des deux points et que la valeur de chaîne qu'il prend est à droite.
Notez que Array.forEach
est JavaScript 1.6 - vous souhaiterez peut-être utiliser une boîte à outils pour une compatibilité maximale.
Ce moyen simple ...
var string = "{firstName:'name1', lastName:'last1'}";
eval('var obj='+string);
alert(obj.firstName);
sortie
name1
si vous utilisez JQuery:
var obj = jQuery.parseJSON('{"path":"/img/filename.jpg"}');
console.log(obj.path); // will print /img/filename.jpg
RAPPEL: eval is evil! :RÉ
Vous devez utiliser JSON.parse () pour convertir String en objet:
var obj = JSON.parse('{ "firstName":"name1", "lastName": "last1" }');
Si vous avez une chaîne comme foo: 1, bar: 2
, vous pouvez la convertir en obj valide avec:
str
.split(',')
.map(x => x.split(':').map(y => y.trim()))
.reduce((a, x) => {
a[x[0]] = x[1];
return a;
}, {});
Merci à niggler dans #javascript pour cela.
Mise à jour avec explications:
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)
Documents MDN déroutants:
Démo: http://jsbin.com/hiduhijevu/edit?js,console
Une fonction:
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!
J'ai implémenté une solution en quelques lignes de code qui fonctionne de manière assez fiable.
Avoir un élément HTML comme celui-ci où je veux passer des options personnalisées:
<div class="my-element"
data-options="background-color: #dadada; custom-key: custom-value;">
</div>
une fonction analyse les options personnalisées et renvoie un objet à utiliser quelque part:
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')));
Étant donné que la méthode JSON.parse () requiert que les clés Object soient placées entre guillemets pour fonctionner correctement, nous devons tout d'abord convertir la chaîne en chaîne au format JSON avant d'appeler la méthode 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
Cela fonctionnerait même si la chaîne avait un objet complexe (comme ci-dessous) et serait toujours convertie correctement. Assurez-vous simplement que la chaîne elle-même est entre guillemets 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
string = "firstName:name1, lastName:last1";
Cela fonctionnera:
var fields = string.split(', '),
fieldObject = {};
if( typeof fields === 'object') ){
fields.each(function(field) {
var c = property.split(':');
fieldObject[c[0]] = c[1];
});
}
Cependant ce n'est pas efficace. Qu'est-ce qui se passe quand vous avez quelque chose comme ça:
string = "firstName:name1, lastName:last1, profileUrl:http://localhost/site/profile/1";
split()
divisera 'http'. Je vous suggère donc d'utiliser un délimiteur spécial comme un tuyau
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];
});
}
C’est un code universel, quelle que soit la longueur de votre saisie, mais dans le même schéma s’il existe: séparateur :)
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)
J'utilise JSON5 , et ça marche plutôt bien.
La bonne partie est qu'il contient no eval
et no new Function
, très sûr à utiliser.
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);
});
"objets" tableau aura tous les objets
Dans ton cas
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]);
}