JSのオブジェクトへの文字列


190

私は文字列を持っています

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

今私はそのような1つのオブジェクトobjが必要です

obj = {firstName:name1, lastName:last1}

JSでこれを行うにはどうすればよいですか?


1
name1およびlast1の文字列値または識別子は他の場所で定義されていますか?
2009

1
さらにデータが必要です...キーまたは値にコンマまたはコロンが含まれている場合はどうしますか?
ブラッド

文字列がJSONとしてフォーマットされていない場合は、RegEpを使用してハンドラーを実行する必要がある場合があります。
bitfishxyz 2018年

回答:


165

実際、最善の解決策は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)関数を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();

ただし、関数を渡すことはできません
K2xL

2
それは事実ですが、厳密に言えば関数はどのJSONオブジェクトにも含まれていてはいけません。RPCなどがある場合、または必要に応じて、関数のプロトタイプをjsonに渡し、eval後で行うことができます。
Matej 14年

36
質問にはまったく答えません。誰もが答えに合うように質問を変えたら素晴らしいでしょう。「firstName:name1、lastName:last1」はどのように解析しますか?'{"hello": "world"}'ではありません。
Noel Abrahams 2014

33
これは質問の答えにはなりません。なぜこれほど多くの賛成票があるのか​​はわかりません。質問者(そして私自身、グーグルして、ここにたどり着きました)には、JSON標準に準拠していないため解析できないデータがあります。
アーロンGreenwald

1
var a = "firstName:name1、lastName:last1"; JSON.parse( '{' + a + '}')はエラーをスローします。
アーロンGreenwald

73

文字列は、中括弧がないJSON文字列のように見えます。

これはうまくいくはずです:

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

22
これは潜在的なセキュリティホールです。この方法はお勧めしません。
ブルトン

64
データの出所によって異なります。一部の人々はセキュリティに夢中です。データを制御すれば、解決策を見つけるのにより実用的になる可能性があります。または、キッチンとリビングルームの間に防犯ドアがありますか?
Philippe Leybaert、2009

13
それは機能していません。エラー'SyntaxError:Unexpected token:'が発生します。Chromeで確認しました。
Nyambaa、2011年

12
解決策は、その周りに括弧を必要とします:obj = eval('({' + str + '})');
キリスト教の

12
prc322:eval()はあまり安全ではない(そしてそれは控えめな表現です)ことは誰もが知っていますが、入力文字列が有効なJSON文字列ではなく、入力文字列が他の変数を参照するため、eval()の使用が上記の質問に対する唯一の正しい答えです名前で。
Philippe Leybaert 2013年

50

私が正しく理解している場合:

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

プロパティ名はコロンの左側にあり、それが取る文字列値は右側にあると想定しています。

これArray.forEachはJavaScript 1.6であることに注意してください-互換性を最大にするためにツールキットを使用したい場合があります。


ちょっとCdleary ...あなたは私を助けることができる場合、私は疑問に思う:stackoverflow.com/questions/9357320/...連絡先に別の方法を見つけるcouldntの申し訳ありませんが、あなたがウル答えのコメントを通して除く外
ジェイソン・

1
首相ポスト。この回答は、JavaScriptの基本を非常に明確に使用しているため、すべてのブラウザーで機能するはずです
Michel

このアプローチは良い出発点だったので、答えは役に立ちました。ただし、xecuteには、コンマが含まれる可能性のある文字列を受け入れないという有効な点があります。コードでコンマを使用して文字列を処理する必要がある場合は、一致する引用符のパスをたどることができますが、引用符がエスケープされる場合はまだ検出されません。必要なものを実装して、停止してください。
Patrick Graham

1
質問者が提示したテキストを解析する問題では、「もしも​​」の問題は役に立たない。与えられた例をデータの代表として受け入れることができます。または、解析を中断する「what if」が常に存在する可能性があるため、単純に答えることはできません。

1
ポスターは、有効なJSONではない異常な構造を解析する方法について尋ねました。@cdlearyは、この状況で非常によく質問に答えました。xecute:文字列内のコンマを処理するには、この説明の範囲を超えて、引用またはエスケープのメカニズムが必要になります。
Suncat2000

37

この簡単な方法...

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

出力

name1

これに賛成してください:ALTHOUGH:var string = "{firstName: 'name1'、lastName: 'last1'、f:function(){alert( 'u got hacked ...')}()}"; eval( 'var obj' + string)これはハッキングされる可能性があります...しかし、場合によっては機能するのはそれだけなので、価値があると思います。
コーディ

12

JQueryを使用している場合:

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

覚えておいてください:evalは悪です!:D


7
jQueryはを使用しevalます。globalEval: /** code **/ window[ "eval" ].call( window, data ); /** more code **/
SomeShinyObject 2013年

12
質問の所有者から提供された文字列は、有効なJSON文字列ではありません。したがって、このコードは
役に立ちませ

はい、evalを「制御された」環境(ファイル、ネットワーク、ユーザー入力などの外部データ以外は何でも、その場合「フィルター/検証」されていない場合は危険である可能性があります)でそれを使用しても問題ありません。
mzalazar 2016

10

文字列をオブジェクトに変換するには、JSON.parse()を使用する必要があります。

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

10

JSON.parse()メソッドが正しく機能するには、オブジェクトキーを引用符で囲む必要があるため、JSON.parse()メソッドを呼び出す前に、まず文字列を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

これは、文字列に次のような複雑なオブジェクトが含まれている場合でも機能し、正しく変換されます。文字列自体が一重引用符で囲まれていることを確認してください。

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

あなたがような文字列を持っているならfoo: 1, bar: 2、それを有効なobjに変換することができます:

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

そのため、#javascriptのnigglerに感謝します。

説明で更新:

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)

混乱するMDNドキュメント:

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

関数:

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!

これは、平均的な読者にとってはまったく理解できない答えです。各行が何をするか説明できますか?そして、OPの入力が与えられた場合、結果の出力は何ですか?
not2qubit 2018年

けっこうだ。通常、詳細を説明する時間はなく、役立つビットをドロップしているだけです(特に、まったく同じSOの質問に出くわした場合に備えて)。
corysimmons

1
これは間違いなく最もエレガントなソリューションであり、他の多くの回答とは異なり、実際に質問に答えます。そして、説明ありがとうございます!
Cathy Ha

4

私は数行のコードでソリューションを実装しましたが、これは非常に確実に機能します。

カスタムオプションを渡したい場所に、次のようなHTML要素があります。

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

関数はカスタムオプションを解析し、それをどこかで使用するオブジェクトを返します。

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-一部のフレームワーク/ライブラリのように擬似カスタム属性を作成する代わりに、属性を使用するための+1 。
ジョン

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

ただし、効率的ではありません。次のようなものがあるとどうなりますか:

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

split()「http」を分割します。だから私はあなたがパイプのような特別な区切り文字を使うことを勧めます

 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
ちょうどアイデア-2番目のsplit( ':')の代わりに、indexOf( ":")を使用して最初のコロンで文字列を「手動で」分割し、このコロンまでの文字列の一部をキーとして、コロンの後の残りを値。
Ondrej Vencovsky 2015


1

これは普遍的なコードであり、入力がどのように長くても同じスキーマ内にある場合:セパレーター:)

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

あなたの場合

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はすべてのコストで回避する必要があります。
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);
        });

「objects」配列にはすべてのオブジェクトが含まれます


0

これは古い投稿ですが、質問に対する正しい答えが表示されませんでした。

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

今、あなたは使用することができますobj.firstNameし、obj.lastNameあなたがオブジェクトを正常に行うことができますように値を取得します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.