JavaScript でのオブジェクト階層の圧縮
-
12-09-2019 - |
質問
ネストされたオブジェクトを単一レベルに「圧縮」するための一般的なアプローチはありますか。
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のにオブジェクトグラフをプッシュするためにこれらの関数を使用する単一のをサポートする、のハッシュキー/値ペアの深ます。