web-dev-qa-db-fra.com

Chaîne d'objet dans JS

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?

168
hijibiji

En fait, la meilleure solution consiste à utiliser JSON:

Documentation

JSON.parse(text[, reviver]);

Exemples:

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();
154
code ninja

Votre chaîne ressemble à une chaîne JSON sans les accolades.

Cela devrait fonctionner alors:

obj = eval('({' + str + '})');
63
Philippe Leybaert

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.

49
cdleary

Ce moyen simple ...

var string = "{firstName:'name1', lastName:'last1'}";
eval('var obj='+string);
alert(obj.firstName);

sortie

name1
30
Wianto Wie

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É

12
mzalazar

Vous devez utiliser JSON.parse () pour convertir String en objet:

var obj = JSON.parse('{ "firstName":"name1", "lastName": "last1" }');
8
Grigor IWT

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!
5
corysimmons

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')));
4
rodu

É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
2
Faisal Chishti
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];
       });
    }
2
Emeka Mbah

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)
1
panatoni

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.

1
James Yang
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

0
comeOnGetIt

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]);
}
0
Vahag Chakhoyan