복붙노트

[JQUERY] 문자열 경로에 의해 중첩 된 자바 스크립트 객체와 배열 액세스

JQUERY

문자열 경로에 의해 중첩 된 자바 스크립트 객체와 배열 액세스

해결법


  1. 1.난 그냥 내가 이미 가지고 몇 가지 유사한 코드를 기반으로이,이 일에 표시했다 :

    난 그냥 내가 이미 가지고 몇 가지 유사한 코드를 기반으로이,이 일에 표시했다 :

    Object.byString = function(o, s) {
        s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
        s = s.replace(/^\./, '');           // strip a leading dot
        var a = s.split('.');
        for (var i = 0, n = a.length; i < n; ++i) {
            var k = a[i];
            if (k in o) {
                o = o[k];
            } else {
                return;
            }
        }
        return o;
    }
    

    용법::

    Object.byString(someObj, 'part3[0].name');
    

    http://jsfiddle.net/alnitak/hEsys/에서 작동하는 데모를 참조하십시오

    EDIT 일부는 가장 왼쪽 인덱스가 개체 내에서 올바르게 중첩 된 항목에 해당하지 않는 문자열을 전달하는 경우이 코드는 오류가 발생합니다 것으로 나타났습니다. 이것은 유효한 관심사이지만, 호출이 아닌 자동으로 잘못된 인덱스 정의되지 않은 돌려주는이 기능을 갖는 경우 이럴 가장 try / catch 블록으로 해결.


  2. 2.이 솔루션 I의 사용이다 :

    이 솔루션 I의 사용이다 :

    function resolve(path, obj=self, separator='.') {
        var properties = Array.isArray(path) ? path : path.split(separator)
        return properties.reduce((prev, curr) => prev && prev[curr], obj)
    }
    

    사용 예제 :

    // accessing property path on global scope
    resolve("document.body.style.width")
    // or
    resolve("style.width", document.body)
    
    // accessing array indexes
    // (someObject has been defined in the question)
    resolve("part3.0.size", someObject) // returns '10'
    
    // accessing non-existent properties
    // returns undefined when intermediate properties are not defined:
    resolve('properties.that.do.not.exist', {hello:'world'})
    
    // accessing properties with unusual keys by changing the separator
    var obj = { object: { 'a.property.name.with.periods': 42 } }
    resolve('object->a.property.name.with.periods', obj, '->') // returns 42
    
    // accessing properties with unusual keys by passing a property name array
    resolve(['object', 'a.property.name.with.periods'], obj) // returns 42
    

    제한 사항 :


  3. 3.이것은 지금 _.get (OBJ, 재산)을 사용 lodash에 의해 지원됩니다. https://lodash.com/docs#get 참조

    이것은 지금 _.get (OBJ, 재산)을 사용 lodash에 의해 지원됩니다. https://lodash.com/docs#get 참조

    워드 프로세서에서 예 :

    var object = { 'a': [{ 'b': { 'c': 3 } }] };
    
    _.get(object, 'a[0].b.c');
    // → 3
    
    _.get(object, ['a', '0', 'b', 'c']);
    // → 3
    
    _.get(object, 'a.b.c', 'default');
    // → 'default'
    

  4. 4.ES6 : 바닐라 JS 내 하나 개의 라인 (대신 오류를주는 찾을 수없는 경우가 null을 반환) :

    ES6 : 바닐라 JS 내 하나 개의 라인 (대신 오류를주는 찾을 수없는 경우가 null을 반환) :

    'path.string'.split('.').reduce((p,c)=>p&&p[c]||null, MyOBJ)
    

    또는 예 :

    'a.b.c'.split('.').reduce((p,c)=>p&&p[c]||null, {a:{b:{c:1}}})
    

    옵션 체인 연산자 :

    'a.b.c'.split('.').reduce((p,c)=>p?.[c], {a:{b:{c:1}}})
    

    준비는 0과 음수, 잘못된 인식 기능을 사용하고 매개 변수로 기본값을 그대로 사용하는 경우 :

    const resolvePath = (object, path, defaultValue) => path
       .split('.')
       .reduce((o, p) => o ? o[p] : defaultValue, object)
    

    사용하는 예 :

    resolvePath(window,'document.body') => <body>
    resolvePath(window,'document.body.xyz') => undefined
    resolvePath(window,'document.body.xyz', null) => null
    resolvePath(window,'document.body.xyz', 1) => 1
    

    보너스:

    (ROB-고든 @에 의해 요청 된) 경로를 사용할 수를 설정하려면 :

    const setPath = (object, path, value) => path
       .split('.')
       .reduce((o,p,i) => o[p] = path.split('.').length === ++i ? value : o[p] || {}, object)
    

    예:

    let myVar = {}
    setPath(myVar, 'a.b.c', 42) => 42
    console.log(myVar) => {a: {b: {c: 42}}}
    

    []와 액세스 배열 :

    const resolvePath = (object, path, defaultValue) => path
       .split(/[\.\[\]\'\"]/)
       .filter(p => p)
       .reduce((o, p) => o ? o[p] : defaultValue, object)
    

    예:

    const myVar = {a:{b:[{c:1}]}}
    resolvePath(myVar,'a.b[0].c') => 1
    resolvePath(myVar,'a["b"][\'0\'].c') => 1
    

  5. 5.당신은 문자열을 직접 구문 분석해야 할 것이다 :

    당신은 문자열을 직접 구문 분석해야 할 것이다 :

    function getProperty(obj, prop) {
        var parts = prop.split('.');
    
        if (Array.isArray(parts)) {
            var last = parts.pop(),
            l = parts.length,
            i = 1,
            current = parts[0];
    
            while((obj = obj[current]) && i < l) {
                current = parts[i];
                i++;
            }
    
            if(obj) {
                return obj[last];
            }
        } else {
            throw 'parts is not valid array';
        }
    }
    

    당신은 또한 점 표기법으로 배열 인덱스를 정의하는 것이이 필요합니다 :

    var part3name1 = "part3.0.name";
    

    그것은 구문 분석 쉬워집니다.

    데모


  6. 6.또한 객체의 내부 배열 / 배열에 대한 작동합니다. 잘못된 값에 대한 방어.

    또한 객체의 내부 배열 / 배열에 대한 작동합니다. 잘못된 값에 대한 방어.

    / ** * 객체 / 배열 중첩 항목을 검색 * @param {오브젝트 | 배열} OBJ * @param 문자열 {}로 분리 도트 * @param {} * DEF 기본값 (결과는 정의되지 않은 경우) * @returns {*} * / 함수 경로 (DEF OBJ, 경로) { var에 나는, 렌; {( '.'; I <렌 I ++ 난 (), LEN path.length = 0, = 경로를 path.split =) 미국 만약 데프 반환 (OBJ || 대해서 typeof (OBJ) == '객체'!!) OBJ = OBJ [경로 [I]; } DEF (OBJ === 정의) 돌아 가면; OBJ 반환; } ////////////////////////// // 테스트 // ////////////////////////// VAR의 도착 = 참 { "SP ACE 'TRUE} 사실] VAR OBJ = { 'SP 에이스': 사실, , 언 : 편곡, 중첩 : { 'dotted.str.ing': 사실} arr3 : 도착 } shouldThrow (`경로 (OBJ "arr.0") '); shouldBeDefined (`경로 (OBJ "도착 [0]") '); shouldBeEqualToNumber (`경로 (OBJ "arr.length") ', 3); shouldBeTrue (`경로 (OBJ "SP 에이스") '); shouldBeEqualToString (`경로 (OBJ "none.existed.prop", "대체") ', "대체"); shouldBeTrue는 ( '경로 (OBJ "중첩') 'dotted.str.ing']); <스크립트 SRC = "https://cdn.rawgit.com/coderek/e7b30bac7634a50ad8fd/raw/174b6634c8f57aa8aac0716c5b7b2a7098e03584/js-test.js">


  7. 7.평가를 사용하여 :

    평가를 사용하여 :

    var part1name = eval("someObject.part1.name");
    

    오류에 정의되지 않은 반환하는 포장

    function path(obj, path) {
        try {
            return eval("obj." + path);
        } catch(e) {
            return undefined;
        }
    }
    

    http://jsfiddle.net/shanimal/b3xTw/

    평가의 힘을 휘두르는 때 상식과주의를하시기 바랍니다. 그것은 당신이 컴퓨터를 켭 경우 사지를 절단 것이다 90 %의 확률이있다, 라이트 세이버 같은 비트입니다. 그 모든 사람을위한.


  8. 8.당신은 트릭 다음과 같은 간단한와 외부 자바 스크립트 라이브러리없이 점 표기법 깊은 객체 멤버의 값을 얻을 관리 할 수 ​​있습니다 :

    당신은 트릭 다음과 같은 간단한와 외부 자바 스크립트 라이브러리없이 점 표기법 깊은 객체 멤버의 값을 얻을 관리 할 수 ​​있습니다 :

    new Function('_', 'return _.' + path)(obj);
    

    여기서 someObject에서 part1.name의 값을 얻기 위해 귀하의 경우에는 단지 수행

    new Function('_', 'return _.part1.name')(someObject);
    

    다음은 간단한 바이올린 데모는 다음과 같습니다 https://jsfiddle.net/harishanchu/oq5esowf/


  9. 9.이것은 아마도 하루의 빛을 보지 못할 것입니다 ...하지만 여기 어쨌든입니다.

    이것은 아마도 하루의 빛을 보지 못할 것입니다 ...하지만 여기 어쨌든입니다.

    // "하나 라이너"(ES6) CONST deep_value = (OBJ 경로) => 통로 .replace (/ \ [| \].? '.'\ / g) .스플릿('.') .filter (S => S) .reduce ((ACC는, 발은) => && ACC ACC [발] OBJ); // ... 그리고 그게 다야. VAR 여기서 someObject = { '1 부' : { '이름': '1 부' '크기': '20', '수량': '50' }, '2 부' : { '이름': '2 부' '크기': '15', '수량': '60' }, '3 편'[ { '이름': '제 3A' '크기': '10', '수량': '20' } // ... ] }; CONSOLE.LOG (deep_value (여기서 someObject "part1.name")); // 1 부 CONSOLE.LOG (deep_value (여기서 someObject "part2.qty")); // (60) CONSOLE.LOG (deep_value (여기서 someObject "파트 3 [0] .name을")); // 제 3A


  10. 10.그것은 lodash와 1 라이너입니다.

    그것은 lodash와 1 라이너입니다.

    const deep = { l1: { l2: { l3: "Hello" } } };
    const prop = "l1.l2.l3";
    const val = _.reduce(prop.split('.'), function(result, value) { return result ? result[value] : undefined; }, deep);
    // val === "Hello"
    

    또는 더 나은 ...

    const val = _.get(deep, prop);
    

    또는 ES6 버전 승 / 감소 ...

    const val = prop.split('.').reduce((r, val) => { return r ? r[val] : undefined; }, deep);
    

    Plunker


  11. 11.난 당신이 요구 생각 :

    난 당신이 요구 생각 :

    var part1name = someObject.part1.name;
    var part2quantity = someObject.part2.qty;
    var part3name1 =  someObject.part3[0].name;
    

    이 요구 될 수있다 :

    var part1name = someObject["part1"]["name"];
    var part2quantity = someObject["part2"]["qty"];
    var part3name1 =  someObject["part3"][0]["name"];
    

    이는 모두 작동합니다

    아니면이 요구된다

    var partName = "part1";
    var nameStr = "name";
    
    var part1name = someObject[partName][nameStr];
    

    마지막으로이 요구 될 수있다

    var partName = "part1.name";
    
    var partBits = partName.split(".");
    
    var part1name = someObject[partBits[0]][partBits[1]];
    

  12. 12.나는 많은면에서 더 빠른 것 더 많은 방법을 제공합니다 : 여기

    나는 많은면에서 더 빠른 것 더 많은 방법을 제공합니다 : 여기

    옵션 1 : 스플릿 문자열입니다. 또는 [나] 또는 '또는 "빈 항목을 건너 뛰고, 그것을 역.

    function getValue(path, origin) {
        if (origin === void 0 || origin === null) origin = self ? self : this;
        if (typeof path !== 'string') path = '' + path;
        var parts = path.split(/\[|\]|\.|'|"/g).reverse(), name; // (why reverse? because it's usually faster to pop off the end of an array)
        while (parts.length) { name=parts.pop(); if (name) origin=origin[name]; }
        return origin;
    }
    

    옵션 2 (평가 제외하고, 모든의 가장 빠름) : 낮은 수준의 문자 스캔 (아무 정규식 / 분할 / 등, 그냥 빨리 문자 스캔). 주 : 인덱스에 대해 따옴표를 지원하지 않습니다이 하나.

    function getValue(path, origin) {
        if (origin === void 0 || origin === null) origin = self ? self : this;
        if (typeof path !== 'string') path = '' + path;
        var c = '', pc, i = 0, n = path.length, name = '';
        if (n) while (i<=n) ((c = path[i++]) == '.' || c == '[' || c == ']' || c == void 0) ? (name?(origin = origin[name], name = ''):(pc=='.'||pc=='['||pc==']'&&c==']'?i=n+2:void 0),pc=c) : name += c;
        if (i==n+2) throw "Invalid path: "+path;
        return origin;
    } // (around 1,000,000+/- ops/sec)
    

    옵션 3 : (새 : 지원 따옴표로 확장 옵션 2 - 조금 느리게,하지만 여전히 빠른)

    function getValue(path, origin) {
        if (origin === void 0 || origin === null) origin = self ? self : this;
        if (typeof path !== 'string') path = '' + path;
        var c, pc, i = 0, n = path.length, name = '', q;
        while (i<=n)
            ((c = path[i++]) == '.' || c == '[' || c == ']' || c == "'" || c == '"' || c == void 0) ? (c==q&&path[i]==']'?q='':q?name+=c:name?(origin?origin=origin[name]:i=n+2,name='') : (pc=='['&&(c=='"'||c=="'")?q=c:pc=='.'||pc=='['||pc==']'&&c==']'||pc=='"'||pc=="'"?i=n+2:void 0), pc=c) : name += c;
        if (i==n+2 || name) throw "Invalid path: "+path;
        return origin;
    }
    

    JSPerf : http://jsperf.com/ways-to-dereference-a-delimited-property-string/3

    "평가는 (...)"아직 (이다 현명한 성능)하지만 왕이다. 당신이 직접 통제하에 속성 경로가있는 경우 (속도가 필요한 경우 특히) '평가'를 사용하여 문제가 안된다. "와이어를 통해"속성 경로를 당기는 경우 (라인에하는 것은!? LOL : P), 다음 네, 다른 사용하는 것이 안전합니다. 만 바보 때 사용하는 좋은 이유가 있기 때문에, 전혀 "평가"를 사용 결코 말할 것입니다. 또한, "그것은 더그 크록 포드의 JSON 파서에 사용됩니다." 입력 모두에서 안전하고 아무런 문제가없는 경우. 그것의 올바른 작업에 적합한 도구를 사용합니다.


  13. 13.이런 경우에, 사람의 나중에 2017 년에이 질문을 방문하고 기억하기 쉬운 방법을 찾고, 여기에 액세스 중첩에 정교한 블로그 게시물에 의해 속여되지 않고 자바 스크립트에서 객체의

    이런 경우에, 사람의 나중에 2017 년에이 질문을 방문하고 기억하기 쉬운 방법을 찾고, 여기에 액세스 중첩에 정교한 블로그 게시물에 의해 속여되지 않고 자바 스크립트에서 객체의

    정의되지 않은 오류의 특성 'foo는'읽을 수 없습니다

    하자이 예제 구조를 가지고

    const user = {
        id: 101,
        email: 'jack@dev.com',
        personalInfo: {
            name: 'Jack',
            address: [{
                line1: 'westwish st',
                line2: 'washmasher',
                city: 'wallas',
                state: 'WX'
            }]
        }
    }
    

    액세스 중첩 배열 할 수 있도록, 당신은 당신의 자신의 배열 util을 줄여 쓸 수 있습니다.

    const getNestedObject = (nestedObj, pathArr) => {
        return pathArr.reduce((obj, key) =>
            (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
    }
    
    // pass in your object structure as array elements
    const name = getNestedObject(user, ['personalInfo', 'name']);
    
    // to access nested array, just pass in array index as an element the path array.
    const city = getNestedObject(user, ['personalInfo', 'address', 0, 'city']);
    // this will return the city from the first address item.
    

    당신을 위해 모든 작업을 수행 최소한의 라이브러리 typy을 처리하는 뛰어난 유형도 있습니다.

    typy으로, 당신의 코드는 다음과 같이 표시됩니다

    const city = t(user, 'personalInfo.address[0].city').safeObject;
    

    면책 조항 :이 패키지의 저자입니다.


  14. 14.나는이 대답을 발견하지만 AngularJS와에게 문자열 경로 별과는 일을 조금 수정과 $ 범위 속성에 액세스 할 수있는 솔루션을 찾고있는 동안 Speigg의 접근 방식은 매우 단정하고 깨끗합니다 :

    나는이 대답을 발견하지만 AngularJS와에게 문자열 경로 별과는 일을 조금 수정과 $ 범위 속성에 액세스 할 수있는 솔루션을 찾고있는 동안 Speigg의 접근 방식은 매우 단정하고 깨끗합니다 :

    $scope.resolve = function( path, obj ) {
        return path.split('.').reduce( function( prev, curr ) {
            return prev[curr];
        }, obj || this );
    }
    

    그냥 루트 컨트롤러에이 기능을 배치하고 이런 식으로 어떤 자식 범위를 사용 :

    $scope.resolve( 'path.to.any.object.in.scope')
    

  15. 15.나는 아직 문자열 경로로 모든 작업을 할 수있는 패키지를 발견하지 않은, (나는, (기본 수익률)) (수) (삽입하는 지원 내 자신의 빠른 작은 패키지를 작성 세트 () 및 제거 결국 이렇게 ) 작업.

    나는 아직 문자열 경로로 모든 작업을 할 수있는 패키지를 발견하지 않은, (나는, (기본 수익률)) (수) (삽입하는 지원 내 자신의 빠른 작은 패키지를 작성 세트 () 및 제거 결국 이렇게 ) 작업.

    당신은 단어가 아닌 문자로 점 표기법, 괄호, 숫자 인덱스, 문자열 번호 속성 및 키를 사용할 수 있습니다. 간단한 사용법 아래 :

    > var jsocrud = require('jsocrud');
    
    ...
    
    // Get (Read) ---
    > var obj = {
    >     foo: [
    >         {
    >             'key w/ non-word chars': 'bar'
    >         }
    >     ]
    > };
    undefined
    
    > jsocrud.get(obj, '.foo[0]["key w/ non-word chars"]');
    'bar'
    

    https://www.npmjs.com/package/jsocrud

    https://github.com/vertical-knowledge/jsocrud


  16. 16.

    /**
     * Access a deep value inside a object 
     * Works by passing a path like "foo.bar", also works with nested arrays like "foo[0][1].baz"
     * @author Victor B. https://gist.github.com/victornpb/4c7882c1b9d36292308e
     * Unit tests: http://jsfiddle.net/Victornpb/0u1qygrh/
     */
    function getDeepVal(obj, path) {
        if (typeof obj === "undefined" || obj === null) return;
        path = path.split(/[\.\[\]\"\']{1,2}/);
        for (var i = 0, l = path.length; i < l; i++) {
            if (path[i] === "") continue;
            obj = obj[path[i]];
            if (typeof obj === "undefined" || obj === null) return;
        }
        return obj;
    }
    

    와 일하다

    getDeepVal(obj,'foo.bar')
    getDeepVal(obj,'foo.1.bar')
    getDeepVal(obj,'foo[0].baz')
    getDeepVal(obj,'foo[1][2]')
    getDeepVal(obj,"foo['bar'].baz")
    getDeepVal(obj,"foo['bar']['baz']")
    getDeepVal(obj,"foo.bar.0.baz[1]['2']['w'].aaa[\"f\"].bb")
    

  17. 17.문자열이나 배열 경로 중 하나를 허용 간단한 기능.

    문자열이나 배열 경로 중 하나를 허용 간단한 기능.

    function get(obj, path) {
      if(typeof path === 'string') path = path.split('.');
    
      if(path.length === 0) return obj;
      return get(obj[path[0]], path.slice(1));
    }
    
    const obj = {a: {b: {c: 'foo'}}};
    
    console.log(get(obj, 'a.b.c')); //foo
    

    또는

    console.log(get(obj, ['a', 'b', 'c'])); //foo
    

  18. 18.NPM 모듈은이 일을 지금이 : https://github.com/erictrinh/safe-access

    NPM 모듈은이 일을 지금이 : https://github.com/erictrinh/safe-access

    사용 예제 :

    var access = require('safe-access');
    access(very, 'nested.property.and.array[0]');
    

  19. 19.좋은 감소하는 동안, 나는 대해 forEach 사용 아무도 놀라게하지 오전 :

    좋은 감소하는 동안, 나는 대해 forEach 사용 아무도 놀라게하지 오전 :

    function valueForKeyPath(obj, path){
            const keys = path.split('.');
            keys.forEach((key)=> obj = obj[key]);
            return obj;
        };
    

    테스트


  20. 20.그냥 같은 문제는 최근 성공적으로 https://npmjs.org/package/tea-properties하는 설정도 중첩 된 객체 / 배열을 사용했다 :

    그냥 같은 문제는 최근 성공적으로 https://npmjs.org/package/tea-properties하는 설정도 중첩 된 객체 / 배열을 사용했다 :

    가져 오기:

    var o = {
      prop: {
        arr: [
          {foo: 'bar'}
        ]
      }
    };
    
    var properties = require('tea-properties');
    var value = properties.get(o, 'prop.arr[0].foo');
    
    assert(value, 'bar'); // true
    

    세트:

    var o = {};
    
    var properties = require('tea-properties');
    properties.set(o, 'prop.arr[0].foo', 'bar');
    
    assert(o.prop.arr[0].foo, 'bar'); // true
    

  21. 21.@ webjay의 대답에 의해 영감 : https://stackoverflow.com/a/46008856/4110122

    @ webjay의 대답에 의해 영감 : https://stackoverflow.com/a/46008856/4110122

    난 당신이 / 설정 / 설정 해제를 객체의 값을 얻을하는 데 사용할 수있는이 기능을 만든

    function Object_Manager(obj, Path, value, Action) 
    {
        try
        {
            if(Array.isArray(Path) == false)
            {
                Path = [Path];
            }
    
            let level = 0;
            var Return_Value;
            Path.reduce((a, b)=>{
                level++;
                if (level === Path.length)
                {
                    if(Action === 'Set')
                    {
                        a[b] = value;
                        return value;
                    }
                    else if(Action === 'Get')
                    {
                        Return_Value = a[b];
                    }
                    else if(Action === 'Unset')
                    {
                        delete a[b];
                    }
                } 
                else 
                {
                    return a[b];
                }
            }, obj);
            return Return_Value;
        }
    
        catch(err)
        {
            console.error(err);
            return obj;
        }
    }
    

    이 기능을 사용하려면 :

     // Set
     Object_Manager(Obj,[Level1,Level2,Level3],New_Value, 'Set');
    
     // Get
     Object_Manager(Obj,[Level1,Level2,Level3],'', 'Get');
    
     // Unset
     Object_Manager(Obj,[Level1,Level2,Level3],'', 'Unset');
    

  22. 22.나는 반작용 온라인 상점을 개발하고 있어요. 내가 제출에 함께 원래의 상태를 업데이트 복사 상태 개체의 값을 변경했습니다. 대부분이 복사 된 객체의 구조 변이 때문에 예를 들면 위, 나를 위해 일하지 않았습니다. I는 액세스 및 깊은 중첩 객체 속성의 값을 변경하기위한 함수의 일례를 작동 실측치 : https://lowrey.me/create-an-object-by-path-in-javascript-2/ 여기있다 :

    나는 반작용 온라인 상점을 개발하고 있어요. 내가 제출에 함께 원래의 상태를 업데이트 복사 상태 개체의 값을 변경했습니다. 대부분이 복사 된 객체의 구조 변이 때문에 예를 들면 위, 나를 위해 일하지 않았습니다. I는 액세스 및 깊은 중첩 객체 속성의 값을 변경하기위한 함수의 일례를 작동 실측치 : https://lowrey.me/create-an-object-by-path-in-javascript-2/ 여기있다 :

    const createPath = (obj, path, value = null) => {
      path = typeof path === 'string' ? path.split('.') : path;
      let current = obj;
      while (path.length > 1) {
        const [head, ...tail] = path;
        path = tail;
        if (current[head] === undefined) {
          current[head] = {};
        }
        current = current[head];
      }
      current[path[0]] = value;
      return obj;
    };
    

  23. 23.당신은 ramda 라이브러리를 사용할 수 있습니다.

    당신은 ramda 라이브러리를 사용할 수 있습니다.

    ramda 학습도 쉽게 불변의 객체로 작업하는 데 도움이됩니다.

    
    var obj = {
      a:{
        b: {
          c:[100,101,{
            d: 1000
          }]
        }
      }
    };
    
    
    var lens = R.lensPath('a.b.c.2.d'.split('.'));
    var result = R.view(lens, obj);
    
    
    

    https://codepen.io/ghominejad/pen/BayJZOQ


  24. 24.알니 타크의 답변에 따라.

    알니 타크의 답변에 따라.

    I는 검사에 polyfill 싸서 하나의 연쇄 환원하는 기능을 감소시켰다.

    만약 {(Object.byPath ===는 정의) Object.byPath = (OBJ 경로) => 경로 .replace (/ \ [(\ w +) \] / g '. $ 1') .replace (/^\./ '') .split (/\./ g) .reduce (? REF에서 REF (REF 키) => 키 [키] REF, OBJ) } CONST 데이터 = { foo는 { 바 : [{ 바즈 : 1 }] } } CONSOLE.LOG (Object.byPath (데이터 'foo.bar [0] .baz'))


  25. 25.당신은 시간을 코딩 그것을 모른 채 다른 중첩 된 키에 액세스해야 할 경우 배열 표기법 접근을 사용할 수 있습니다 (이이를 해결하기 위해 사소한 것) :

    당신은 시간을 코딩 그것을 모른 채 다른 중첩 된 키에 액세스해야 할 경우 배열 표기법 접근을 사용할 수 있습니다 (이이를 해결하기 위해 사소한 것) :

    var part1name = someObject['part1']['name'];
    var part2quantity = someObject['part2']['qty'];
    var part3name1 =  someObject['part3'][0]['name'];
    

    그들은 점 표기법 접근에 해당하고, 예를 들어, 런타임에 달라질 수 있습니다 :

    var part = 'part1';
    var property = 'name';
    
    var part1name = someObject[part][property];
    

    동등

    var part1name = someObject['part1']['name'];
    

    또는

    var part1name = someObject.part1.name;
    

    나는이 주소를 귀하의 질문에 희망을 ...

    편집하다

    나는 객체의 값에 액세스하는 XPath 쿼리의 정렬을 유지하기 위해 문자열을 사용하지 않습니다. 당신은 쿼리를 분석하고 내가 다른 경로 (하지를 따를 값을 검색하는 함수를 호출해야로서 :

    var part1name = function(){ return this.part1.name; }
    var part2quantity = function() { return this['part2']['qty']; }
    var part3name1 =  function() { return this.part3[0]['name'];}
    
    // usage: part1name.apply(someObject);
    

    당신이 가진 불안 경우 또는 방법을 적용

    var part1name = function(obj){ return obj.part1.name; }
    var part2quantity = function(obj) { return obj['part2']['qty']; }
    var part3name1 =  function(obj) { return obj.part3[0]['name'];}
    
    // usage: part1name(someObject);
    

    기능은 인터프리터가 구문 오류 등 당신을 위해 그들을 확인, 명확, 짧다.

    그런데, 나는 적절한 시간에 만든 간단한 할당하면 충분이 될 것이라고 생각 ...


  26. 26.여기에 솔루션은 단지 중첩 키를 액세스하기위한 것입니다. 나는 액세스, 추가, 수정 및 키를 삭제하는 일이 필요했습니다. 이것은 내가 생각 해낸 것입니다 :

    여기에 솔루션은 단지 중첩 키를 액세스하기위한 것입니다. 나는 액세스, 추가, 수정 및 키를 삭제하는 일이 필요했습니다. 이것은 내가 생각 해낸 것입니다 :

    var deepAccessObject = function(object, path_to_key, type_of_function, value){
        switch(type_of_function){
            //Add key/modify key
            case 0: 
                if(path_to_key.length === 1){
                    if(value)
                        object[path_to_key[0]] = value;
                    return object[path_to_key[0]];
                }else{
                    if(object[path_to_key[0]])
                        return deepAccessObject(object[path_to_key[0]], path_to_key.slice(1), type_of_function, value);
                    else
                        object[path_to_key[0]] = {};
                }
                break;
            //delete key
            case 1:
                if(path_to_key.length === 1){
                    delete object[path_to_key[0]];
                    return true;
                }else{
                    if(object[path_to_key[0]])
                        return deepAccessObject(object[path_to_key[0]], path_to_key.slice(1), type_of_function, value);
                    else
                        return false;
                }
                break;
            default:
                console.log("Wrong type of function");
        }
    };
    

  27. 27.알니 타크의 대답의 오프 건물 :

    알니 타크의 대답의 오프 건물 :

    if(!Object.prototype.byString){
      //NEW byString which can update values
    Object.prototype.byString = function(s, v, o) {
      var _o = o || this;
          s = s.replace(/\[(\w+)\]/g, '.$1'); // CONVERT INDEXES TO PROPERTIES
          s = s.replace(/^\./, ''); // STRIP A LEADING DOT
          var a = s.split('.'); //ARRAY OF STRINGS SPLIT BY '.'
          for (var i = 0; i < a.length; ++i) {//LOOP OVER ARRAY OF STRINGS
              var k = a[i];
              if (k in _o) {//LOOP THROUGH OBJECT KEYS
                  if(_o.hasOwnProperty(k)){//USE ONLY KEYS WE CREATED
                    if(v !== undefined){//IF WE HAVE A NEW VALUE PARAM
                      if(i === a.length -1){//IF IT'S THE LAST IN THE ARRAY
                        _o[k] = v;
                      }
                    }
                    _o = _o[k];//NO NEW VALUE SO JUST RETURN THE CURRENT VALUE
                  }
              } else {
                  return;
              }
          }
          return _o;
      };
    

    }

    이것은 당신이뿐만 아니라 값을 설정할 수 있습니다!

    나뿐만 아니라이 가진 NPM 패키지와 GitHub의를 만들었습니다


  28. 28.대신 스트링의 배열이 중첩 된 객체 및 배열 예컨대 : adressing 사용될 수있는 "my_field", "another_field를"0 "last_field"10]

    대신 스트링의 배열이 중첩 된 객체 및 배열 예컨대 : adressing 사용될 수있는 "my_field", "another_field를"0 "last_field"10]

    다음은이 배열 표현에 기초한 것이다 필드를 변경 한 예이다. 나는 중첩 된 구조의 상태를 변경 제어 입력 필드에 react.js에서 그런 일을 사용하고 있습니다.

    let state = {
            test: "test_value",
            nested: {
                level1: "level1 value"
            },
            arr: [1, 2, 3],
            nested_arr: {
                arr: ["buh", "bah", "foo"]
            }
        }
    
    function handleChange(value, fields) {
        let update_field = state;
        for(var i = 0; i < fields.length - 1; i++){
            update_field = update_field[fields[i]];
        }
        update_field[fields[fields.length-1]] = value;
    }
    
    handleChange("update", ["test"]);
    handleChange("update_nested", ["nested","level1"]);
    handleChange(100, ["arr",0]);
    handleChange('changed_foo', ["nested_arr", "arr", 3]);
    console.log(state);
    

  29. 29.이전 답변에 따라, 또한 브래킷을 처리 할 수있는 기능을 만들었습니다. 그러나 그 내부에는 점은 분할로 인해 없습니다.

    이전 답변에 따라, 또한 브래킷을 처리 할 수있는 기능을 만들었습니다. 그러나 그 내부에는 점은 분할로 인해 없습니다.

    function get(obj, str) {
      return str.split(/\.|\[/g).map(function(crumb) {
        return crumb.replace(/\]$/, '').trim().replace(/^(["'])((?:(?!\1)[^\\]|\\.)*?)\1$/, (match, quote, str) => str.replace(/\\(\\)?/g, "$1"));
      }).reduce(function(obj, prop) {
        return obj ? obj[prop] : undefined;
      }, obj);
    }
    

  30. 30.// (IE9 +) 두 단계 VAR pathString = "[0] [ '속성'] 등 [3] 다음 내용 [ '최종']."; VAR OBJ = [{ 특성: { 기타 : [1, 2, 3, { 다음: { 마지막 : "성공" } }] } }]; 경로 배열 // 전원을 켜고 문자열 VAR pathArray = pathString .replace (/ \ [ '']? ([\ w] +) '']? \] / g ". $ 1") .스플릿(".") .splice (1); // 추가 객체 프로토 타입 방법 Object.prototype.path = 함수 (경로) { {시도 창 [이] .concat (경로) .reduce (함수 (F, l) { F [1]를 복귀; }); } 캐치 (전자) { console.error (E); } }; // 사용 CONSOLE.LOG (obj.path (pathArray)); CONSOLE.LOG (obj.path ([0 "doesNotExist"]));

    // (IE9 +) 두 단계 VAR pathString = "[0] [ '속성'] 등 [3] 다음 내용 [ '최종']."; VAR OBJ = [{ 특성: { 기타 : [1, 2, 3, { 다음: { 마지막 : "성공" } }] } }]; 경로 배열 // 전원을 켜고 문자열 VAR pathArray = pathString .replace (/ \ [ '']? ([\ w] +) '']? \] / g ". $ 1") .스플릿(".") .splice (1); // 추가 객체 프로토 타입 방법 Object.prototype.path = 함수 (경로) { {시도 창 [이] .concat (경로) .reduce (함수 (F, l) { F [1]를 복귀; }); } 캐치 (전자) { console.error (E); } }; // 사용 CONSOLE.LOG (obj.path (pathArray)); CONSOLE.LOG (obj.path ([0 "doesNotExist"]));

  31. from https://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-and-arays-by-string-path by cc-by-sa and MIT license