質問

ネストされたオブジェクトを単一レベルに「圧縮」するための一般的なアプローチはありますか。

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 2 番目のパラメータに入力します。

いくつかの注意点:

  • 再帰オブジェクトは機能しません。例えば:

    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]"
    

他のヒント

ここでは、迅速一つだが、/ C、それは/配列やNULL値(B / C自分のtypeof戻っ "オブジェクト")W のないの仕事意志B、気をつけます。

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

ここでは簡単 CoffeeScriptののバージョンオフに基づいて<のhref = "https://でstackoverflow.com/questions/963607/compressing-object-hierarchies-in-javascript/965315#965315">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

そして間違いなく繰り返さセパレータおよび他のそのようなtrickinessで失敗し、基本的な非平坦化バージョン、ます:

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、私は Redisのにオブジェクトグラフをプッシュするためにこれらの関数を使用する単一のをサポートする、のハッシュキー/値ペアの深ます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top