Ho una stringa come
string = "firstName:name1, lastName:last1";
ora ho bisogno di un oggetto obj tale che
obj = {firstName:name1, lastName:last1}
Come posso farlo in JS?
Ho una stringa come
string = "firstName:name1, lastName:last1";
ora ho bisogno di un oggetto obj tale che
obj = {firstName:name1, lastName:last1}
Come posso farlo in JS?
Risposte:
In realtà, la soluzione migliore sta usando 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) Passare una funzione 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
seguito.
La tua stringa sembra una stringa JSON senza le parentesi graffe.
Questo dovrebbe funzionare quindi:
obj = eval('({' + str + '})');
obj = eval('({' + str + '})');
Se sto capendo correttamente:
var properties = string.split(', ');
var obj = {};
properties.forEach(function(property) {
var tup = property.split(':');
obj[tup[0]] = tup[1];
});
Suppongo che il nome della proprietà sia a sinistra dei due punti e che il valore della stringa che assume sia a destra.
Nota che Array.forEach
è JavaScript 1.6: potresti voler utilizzare un toolkit per la massima compatibilità.
In questo modo semplice ...
var string = "{firstName:'name1', lastName:'last1'}";
eval('var obj='+string);
alert(obj.firstName);
produzione
name1
se stai usando JQuery:
var obj = jQuery.parseJSON('{"path":"/img/filename.jpg"}');
console.log(obj.path); // will print /img/filename.jpg
RICORDA: eval è malvagio! : D
eval
. globalEval: /** code **/ window[ "eval" ].call( window, data ); /** more code **/
Poiché il metodo JSON.parse () richiede che le chiavi Object siano racchiuse tra virgolette perché funzioni correttamente, prima di chiamare il metodo JSON.parse () dovremmo prima convertire la stringa in una stringa formattata JSON.
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
Funzionerebbe anche se la stringa avesse un oggetto complesso (come il seguente) e sarebbe comunque convertita correttamente. Assicurati solo che la stringa stessa sia racchiusa tra virgolette singole.
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
È necessario utilizzare JSON.parse () per convertire String in un oggetto:
var obj = JSON.parse('{ "firstName":"name1", "lastName": "last1" }');
Se hai una stringa come questa foo: 1, bar: 2
puoi convertirla in un oggetto valido con:
str
.split(',')
.map(x => x.split(':').map(y => y.trim()))
.reduce((a, x) => {
a[x[0]] = x[1];
return a;
}, {});
Grazie a niggler in #javascript per questo.
Aggiornamento con spiegazioni:
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)
Documenti MDN confusi:
Demo: http://jsbin.com/hiduhijevu/edit?js,console
Funzione:
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!
Ho implementato una soluzione in poche righe di codice che funziona in modo abbastanza affidabile.
Avere un elemento HTML come questo in cui voglio passare opzioni personalizzate:
<div class="my-element"
data-options="background-color: #dadada; custom-key: custom-value;">
</div>
una funzione analizza le opzioni personalizzate e restituisce un oggetto per usarlo da qualche 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-
dell'attributo anziché la creazione di attributi pseudo-personalizzati come alcuni framework / librerie.
string = "firstName:name1, lastName:last1";
Questo funzionerà:
var fields = string.split(', '),
fieldObject = {};
if( typeof fields === 'object') ){
fields.each(function(field) {
var c = property.split(':');
fieldObject[c[0]] = c[1];
});
}
Tuttavia non è efficiente. Cosa succede quando hai qualcosa del genere:
string = "firstName:name1, lastName:last1, profileUrl:http://localhost/site/profile/1";
split()
dividerà "http". Quindi ti suggerisco di usare un delimitatore speciale come pipe
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];
});
}
Questo è un codice universale, non importa quanto il tuo input sia lungo ma nello stesso schema se c'è: separatore :)
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)
Sto usando JSON5 , e funziona abbastanza bene.
La parte buona è che contiene no eval
e no new Function
, molto sicuro da usare.
Nel tuo 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);
});
La matrice "oggetti" avrà tutti gli oggetti
So che questo è un vecchio post ma non ho visto la risposta corretta alla domanda.
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);
Ora puoi usare obj.firstName
e obj.lastName
ottenere i valori come faresti normalmente con un oggetto.