Zeichenfolge zum Objekt in JS


190

Ich habe eine Zeichenfolge als

string = "firstName:name1, lastName:last1"; 

jetzt brauche ich ein objekt obj so dass

obj = {firstName:name1, lastName:last1}

Wie kann ich das in JS machen?


1
Sind die Zeichenfolgenwerte oder Bezeichner name1 und last1 an anderer Stelle definiert?
CDLeary

1
Weitere Daten erforderlich ... Was tun Sie, wenn der Schlüssel oder der Wert ein Komma oder einen Doppelpunkt enthält?
Brad

Wenn Ihre Zeichenfolge nicht als JSON formatiert ist, müssen Sie möglicherweise RegEp als Handler verwenden.
Bitfishxyz

Antworten:


165

Die beste Lösung ist die Verwendung von JSON:

Dokumentation

JSON.parse(text[, reviver]);

Beispiele:

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) Übergeben einer Funktion an 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();

Es werden jedoch keine Funktionen übergeben
K2xL

2
Das ist wahr, jedoch sollten Funktionen streng genommen nicht in JSON-Objekten enthalten sein. Dafür haben Sie RPC usw., oder wenn Sie möchten, können Sie den Prototyp einer Funktion an den json übergeben und evalspäter ausführen .
Matej

36
Beantwortet die Frage leider überhaupt nicht. Es wäre wunderbar, wenn jeder die Frage an die Antwort anpassen würde. Wie analysiert man "Vorname: Name1, Nachname: Nachname1"? nicht '{"Hallo": "Welt"}'.
Noel Abrahams

33
Dies beantwortet die Frage nicht, ich weiß nicht, warum es so viele positive Stimmen gibt. Der Fragesteller (und ich selbst, ich habe gegoogelt und bin hier gelandet) haben Daten, die nicht dem JSON-Standard entsprechen und daher nicht analysiert werden können.
Aaron Greenwald

1
var a = "Vorname: Name1, Nachname: Nachname1"; JSON.parse ('{' + a + '}') gibt einen Fehler aus.
Aaron Greenwald

73

Ihre Zeichenfolge sieht aus wie eine JSON-Zeichenfolge ohne geschweifte Klammern.

Das sollte dann funktionieren:

obj = eval('({' + str + '})');

22
Dies ist eine potenzielle Sicherheitslücke. Ich würde diese Methode überhaupt nicht empfehlen.
Breton

64
Es kommt darauf an, woher die Daten kommen. Einige Leute sind von Sicherheit besessen. Wenn Sie Ihre Daten kontrollieren, können Sie pragmatischer nach Lösungen suchen. Oder haben Sie eine einbruchssichere Tür zwischen Küche und Wohnzimmer?
Philippe Leybaert

13
Das funktioniert nicht. Es gibt den Fehler 'SyntaxError: Unerwartetes Token:' . Ich habe es in Chrome überprüft.
Nyambaa

12
Die Lösung benötigt Klammern:obj = eval('({' + str + '})');
Christian

12
prc322: Jeder weiß, dass eval () nicht sehr sicher ist (und das ist eine Untertreibung), aber die Verwendung von eval () ist die einzig richtige Antwort auf die obige Frage, da die Eingabezeichenfolge keine gültige JSON-Zeichenfolge ist UND die Eingabezeichenfolge auf andere Variablen verweist namentlich.
Philippe Leybaert

50

Wenn ich richtig verstehe:

var properties = string.split(', ');
var obj = {};
properties.forEach(function(property) {
    var tup = property.split(':');
    obj[tup[0]] = tup[1];
});

Ich gehe davon aus, dass sich der Eigenschaftsname links vom Doppelpunkt und der angenommene Zeichenfolgenwert rechts befindet.

Beachten Sie, dass Array.forEaches sich um JavaScript 1.6 handelt. Möglicherweise möchten Sie ein Toolkit verwenden, um maximale Kompatibilität zu gewährleisten.


Hey Cdleary ... ich frage mich, ob du mir helfen kannst: stackoverflow.com/questions/9357320/… Entschuldigung, ich konnte keinen anderen Weg finden, dich zu kontaktieren, außer durch Kommentare zu deinen Antworten
Jason

1
Präfekt Post. Diese Antwort verwendet die Grundlagen von JavaScript sehr klar und sollte dabei in jedem Browser funktionieren
Michel

Ich fand, dass dieser Ansatz ein guter Anfang war, daher war die Antwort nützlich. Xecute hat jedoch einen gültigen Punkt, an dem Zeichenfolgen mit Kommas möglicherweise nicht berücksichtigt werden. Sie könnten den Pfad übereinstimmender Anführungszeichen beschreiten, wenn Ihr Code Zeichenfolgen mit Kommas verarbeiten muss, aber Sie werden immer noch keine Fälle abfangen, in denen die Anführungszeichen maskiert sind. Implementieren Sie einfach das, was Sie brauchen, und hören Sie dann auf.
Patrick Graham

1
In einer Frage des vom Fragesteller präsentierten Parsing-Textes sind Fragen des "Was wäre wenn" nutzlos. Wir können das angegebene Beispiel als repräsentativ für die Daten akzeptieren oder einfach nicht antworten, da es immer ein "Was wäre wenn" geben könnte , das die Analyse unterbricht.

1
Auf dem Poster wurde gefragt, wie eine ungewöhnliche Struktur analysiert werden soll, die nicht für JSON gültig ist. @cdleary hat die Frage unter den gegebenen Umständen sehr gut beantwortet. xecute: Die Behandlung eines Kommas in einer Zeichenfolge würde einen Anführungszeichen- oder Escape-Mechanismus erfordern, der über den Rahmen dieser Diskussion hinausgeht.
Suncat2000

37

Dieser einfache Weg ...

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

Ausgabe

name1

Upvote dafür, ALTHOUGH: var string = "{Vorname: 'Name1', Nachname: 'Nachname1', f: Funktion () {Warnung ('Du wurdest gehackt ...')} ()}"; eval ('var obj' + string) Dies könnte dich hacken lassen ... aber ich denke, es lohnt sich, weil es das einzige ist, was in einigen Fällen funktioniert.
Cody

12

Wenn Sie JQuery verwenden:

var obj = jQuery.parseJSON('{"path":"/img/filename.jpg"}');
console.log(obj.path); // will print /img/filename.jpg

ERINNERN SIE SICH: eval ist böse! : D.


7
jQuery verwendet eval. globalEval: /** code **/ window[ "eval" ].call( window, data ); /** more code **/
SomeShinyObject

12
Die vom Frageneigentümer bereitgestellte Zeichenfolge ist keine gültige JSON-Zeichenfolge. Also, dieser Code ist nutzlos ...
xecute

Ja, eval ist nicht böse, wenn Sie es in einer "kontrollierten" Umgebung verwenden (alles andere als externe Daten wie Dateien, Netzwerk- oder Benutzereingaben, in diesen Fällen kann es gefährlich sein, wenn es nicht "gefiltert / validiert" wird).
Mzalazar

10

Sie müssen JSON.parse () verwenden, um String in ein Objekt zu konvertieren:

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

10

Da für die JSON.parse () -Methode die Objektschlüssel in Anführungszeichen eingeschlossen sein müssen, damit sie ordnungsgemäß funktionieren, müssen wir die Zeichenfolge zunächst in eine JSON-formatierte Zeichenfolge konvertieren, bevor wir die JSON.parse () -Methode aufrufen.

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

Dies würde auch dann funktionieren, wenn die Zeichenfolge ein komplexes Objekt hat (wie das folgende) und dennoch korrekt konvertiert wird. Stellen Sie einfach sicher, dass die Zeichenfolge selbst in einfache Anführungszeichen eingeschlossen ist.

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


8

Wenn Sie einen String wie diesen haben foo: 1, bar: 2, können Sie ihn in ein gültiges Objekt konvertieren mit:

str
  .split(',')
  .map(x => x.split(':').map(y => y.trim()))
  .reduce((a, x) => {
    a[x[0]] = x[1];
    return a;
  }, {});

Danke an Niggler in #javascript dafür.

Update mit Erklärungen:

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)

Verwirrende MDN-Dokumente:

Demo: http://jsbin.com/hiduhijevu/edit?js,console

Funktion:

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!

Dies ist eine völlig unverständliche Antwort für den Durchschnittsleser. Können Sie erklären, was jede Zeile tut? Und was ist die resultierende Ausgabe angesichts der Eingabe von OP?
not2qubit

Meinetwegen. Normalerweise habe ich keine Zeit, um Details zu detaillieren, und ich lasse nur hilfreiche Teile fallen (insbesondere für den Fall, dass ich später auf genau dieselbe SO-Frage stoße), aber ich habe es verstanden.
Corysimmons

1
Dies ist definitiv die eleganteste Lösung und beantwortet die Frage im Gegensatz zu vielen anderen Antworten. Und danke für die Erklärung!
Cathy Ha

4

Ich habe eine Lösung in wenigen Codezeilen implementiert, die ziemlich zuverlässig funktioniert.

Mit einem HTML-Element wie diesem möchte ich benutzerdefinierte Optionen übergeben:

<div class="my-element"
    data-options="background-color: #dadada; custom-key: custom-value;">
</div>

Eine Funktion analysiert die benutzerdefinierten Optionen und gibt ein Objekt zurück, um es irgendwo zu verwenden:

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

+1 für die Verwendung des data-Attributs anstelle der Erstellung von pseudo-benutzerdefinierten Attributen wie einigen Frameworks / Bibliotheken.
John

3
string = "firstName:name1, lastName:last1";

Das wird funktionieren:

var fields = string.split(', '),
    fieldObject = {};

if( typeof fields === 'object') ){
   fields.each(function(field) {
      var c = property.split(':');
      fieldObject[c[0]] = c[1];
   });
}

Es ist jedoch nicht effizient. Was passiert, wenn Sie so etwas haben:

string = "firstName:name1, lastName:last1, profileUrl:http://localhost/site/profile/1";

split()wird 'http' teilen. Daher schlage ich vor, dass Sie ein spezielles Trennzeichen wie Pipe verwenden

 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
Nur eine Idee - anstelle der zweiten Teilung (':') können Sie die Zeichenfolge "manuell" durch den ERSTEN Doppelpunkt mit indexOf (":") teilen und den Teil der Zeichenfolge bis zu diesem Doppelpunkt als Schlüssel und den Rest nach dem Doppelpunkt als betrachten der Wert.
Ondrej Vencovsky

2

Ich benutze JSON5 und es funktioniert ziemlich gut.

Das Gute daran ist, dass es keine eval und keine enthält new Function, sehr sicher zu bedienen.


1

Dies ist universeller Code, egal wie lang Ihre Eingabe ist, aber im selben Schema, wenn es Folgendes gibt: Trennzeichen :)

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)

0

In deinem Fall

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

3
eval sollte unbedingt vermieden werden.
Alex

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

Das Array "Objekte" enthält alle Objekte


0

Ich weiß, dass dies ein alter Beitrag ist, habe aber nicht die richtige Antwort auf die Frage gefunden.

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);

Jetzt können Sie die Werte verwenden obj.firstNameund obj.lastNameabrufen, wie Sie es normalerweise mit einem Objekt tun würden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.