문제

중첩 된 객체를 단일 레벨로 "압축"하는 일반적인 접근 방식이 있습니까?

var myObj = {
    a: "hello",
    b: {
        c: "world"
    }
}

compress(myObj) == {
    a: "hello",
    b_c: "world"
}

나는 몇 가지 재귀가 관련 될 것이라고 생각하지만, 나는 여기에서 바퀴를 재발 명 할 필요가 없다고 생각했다 ...!?

도움이 되었습니까?

해결책

function flatten(obj, includePrototype, into, prefix) {
    into = into || {};
    prefix = prefix || "";

    for (var k in obj) {
        if (includePrototype || obj.hasOwnProperty(k)) {
            var prop = obj[k];
            if (prop && typeof prop === "object" &&
                !(prop instanceof Date || prop instanceof RegExp)) {
                flatten(prop, includePrototype, into, prefix + k + "_");
            }
            else {
                into[prefix + k] = prop;
            }
        }
    }

    return into;
}

통과하여 상속 된 회원을 포함시킬 수 있습니다 true 두 번째 매개 변수로.

몇 가지 경고 :

  • 재귀 객체는 작동하지 않습니다. 예를 들어:

    var o = { a: "foo" };
    o.b = o;
    flatten(o);
    

    예외가 발생할 때까지 되풀이됩니다.

  • Ruquay의 대답과 마찬가지로 이것은 일반적인 객체 속성처럼 배열 요소를 끌어냅니다. 배열을 그대로 유지하려면 추가 "|| prop instanceof Array"예외에.

  • 다른 창이나 프레임의 개체에서 이것을 호출하면 날짜와 정규식이 포함되지 않습니다. instanceof 제대로 작동하지 않습니다. 다음과 같은 기본 Tostring 메소드로 교체하여이를 고칠 수 있습니다.

    Object.prototype.toString.call(prop) === "[object Date]"
    Object.prototype.toString.call(prop) === "[object RegExp]"
    Object.prototype.toString.call(prop) === "[object Array]"
    

다른 팁

여기에 빠른 것이 있지만 조심하세요. B/C ~ 아니다 배열 및 null 값이있는 작업 (B/ C 유형은 "개체"를 반환합니다).

var flatten = function(obj, prefix) {
  if(typeof prefix === "undefined") {
    prefix = "";
  }
  var copy = {};
  for (var p in obj) {
    if(obj.hasOwnProperty(p)) {
      if(typeof obj[p] === "object") {
        var tmp = flatten(obj[p], p + "_");
        for(var q in tmp) {
          if(tmp.hasOwnProperty(q)) {
            copy[prefix + q] = tmp[q];
          }
        }
      }
      else {
        copy[prefix + p] = obj[p];
      }
    }
  }
  return copy;
}

var myObj = {
  a: "level 1",
  b: {
    a: "level 2",
    b: {
      a: "level 3",
      b: "level 3"
    }
  }
}

var flattened = flatten(myObj);

여기가 빨리 있습니다 커피 스크립트 버전을 기반으로합니다 Matthew Crumley의 대답 (나는 사용하지 않았다 includePrototype 필요하지 않았기 때문에) :

flatten = (obj, into = {}, prefix = '', sep = '_') ->
  for own key, prop of obj
    if typeof prop is 'object' and prop not instanceof Date and prop not instanceof RegExp
      flatten prop, into, prefix + key + sep, sep
    else
      into[prefix + key] = prop
  into

그리고 반복적 인 분리기 및 기타 속임수로 의심 할 여지없이 실패한 기본적인 unflatten 버전.

unflatten = (obj, into = {}, sep = '_') ->
  for own key, prop of obj
    subKeys = key.split sep
    sub = into
    sub = (sub[subKey] or= {}) for subKey in subKeys[...-1]
    sub[subKeys.pop()] = prop
  into

fwiw, 나는이 기능을 사용하여 객체 그래프를 푸시합니다. 레디스 해시, 단일 키/값 쌍의 깊이 만 지원합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top