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.