JS에서 객체로의 문자열


190

나는 문자열을 가지고있다.

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

이제 하나의 객체 obj가 필요합니다.

obj = {firstName:name1, lastName:last1}

JS에서 어떻게 할 수 있습니까?


1
name1 및 last1 문자열 값 또는 다른 곳에 정의 된 식별자입니까?
cdleary

1
더 많은 데이터가 필요합니다. 키나 값에 쉼표 나 콜론이 있으면 어떻게해야합니까?
Brad

문자열 형식이 JSON이 아닌 경우 RegEp를 사용하여 처리해야 할 수 있습니다.
bitfishxyz

답변:


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

36
전혀 두려워하지 않습니다. 모든 사람이 답을 맞추기 위해 질문을 바꾸었다면 정말 좋을 것입니다. "firstName : name1, lastName : last1"을 어떻게 구문 분석합니까? '{ "hello": "world"}'가 아닙니다.
Noel Abrahams

33
이것은 질문에 대한 답이 아니며 왜 그렇게 많은 공감대가 있는지 모르겠습니다. 질문자 (그리고 나 자신은 Google에서 검색하고 끝났다)는 JSON 표준을 준수하지 않으므로 구문 분석 할 수없는 데이터를 가지고 있습니다.
Aaron Greenwald

1
var a = "firstName : name1, lastName : last1"; JSON.parse ( '{'+ a + '}')에서 오류가 발생합니다.
Aaron Greenwald

73

문자열은 중괄호가없는 JSON 문자열처럼 보입니다.

그러면 작동합니다.

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

22
이것은 잠재적 인 보안 허점입니다. 이 방법을 전혀 권장하지 않습니다.
Breton

65
데이터의 출처에 따라 다릅니다. 어떤 사람들은 안전에 집착합니다. 데이터를 제어하면 솔루션을 찾는 데 더 실용적이 될 수 있습니다. 아니면 부엌과 거실 사이에 도난 방지 도어가 있습니까?
Philippe Leybaert

13
작동하지 않습니다. 'SyntaxError : Unexpected token :' 오류가 발생 합니다. Chrome에서 확인했습니다.
Nyambaa

12
해결책은 주위에 괄호가 필요합니다.obj = eval('({' + str + '})');
Christian

12
prc322 : 누구나 eval ()이 안전하지 않다는 것을 알고 있지만 입력 문자열이 유효한 JSON 문자열이 아니며 입력 문자열이 다른 변수를 참조하기 때문에 eval ()을 사용하는 것이 위의 질문에 대한 정답입니다 이름으로.
Philippe Leybaert

50

내가 올바르게 이해한다면 :

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

속성 이름이 콜론의 왼쪽에 있고 문자열 값이 오른쪽에 있다고 가정합니다.

참고 Array.forEach자바 스크립트 1.6 - 당신은 최대의 호환성을 위해 툴킷을 사용할 수 있습니다.


안녕하세요 Cdleary ... 도움이 될지 궁금합니다 : stackoverflow.com/questions/9357320 / ... 죄송합니다 . 답변에 대한 의견을 제외한 다른 연락 방법을 찾을 수 없습니다.
Jason

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

이것에 대한 찬성, 다음과 같이 : var string = "{firstName : 'name1', lastName : 'last1', f : function () {alert ( 'u got hacked ...')} ()}"; eval ( 'var obj'+ string) 이렇게하면 해킹 당할 수 있습니다.하지만 가치가 있다고 생각하는 경우도 있습니다.
Cody

12

JQuery를 사용하는 경우 :

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

기억하세요 : 평가는 악입니다! :디


7
jQuery는를 사용합니다 eval. globalEval: /** code **/ window[ "eval" ].call( window, data ); /** more code **/
SomeShinyObject 1

12
질문 소유자가 제공 한 문자열이 유효한 JSON 문자열이 아닙니다. 따라서이 코드는 쓸모가 없습니다.
xecute

예, "제어 된"환경 (파일, 네트워크 또는 사용자 입력과 같은 외부 데이터 이외의 것)을 사용하는 경우 eval은 악하지 않습니다.
mzalazar

11

JSON.parse () 메서드를 사용하려면 Object 키를 따옴표 안에 넣어야 제대로 작동 할 수 있으므로 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


10

String을 Object로 변환하려면 JSON.parse ()를 사용해야합니다.

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

9

당신이 같은 문자열을 가지고 있다면 다음 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

1
그럴 수 있지. 일반적으로 나는 물건을 자세히 설명 할 시간이 없으며 유용한 비트를 떨어 뜨리고 있습니다 (특히 같은 정확한 SO 질문에 부딪 칠 경우).
corysimmons

2
이것은 확실히 가장 우아한 해결책이며 실제로 다른 답변과 달리 질문에 대답합니다. 설명 감사합니다!
캐시 하

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입니다 .
John

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
단지 아이디어-두 번째 split ( ':') 대신 indexOf ( ":")를 사용하여 FIRST 콜론으로 "수동으로"문자열을 분할하고이 콜론까지의 문자열 부분을 키로, 콜론 뒤의 나머지 부분을 다음과 같이 고려할 수 있습니다. 가치.
Ondrej Vencovsky

2

이것은 입력이 아무리 길더라도 동일한 스키마에있는 보편적 인 코드입니다 : separator :)

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

"객체"배열에는 모든 객체가 있습니다


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.