再帰は必要ありません!
[key, value]
次の関数関数は、キーの値を配列として、最も深いものから最も深いものの順にエントリを出力します。
function deepEntries( obj ){
'use-strict';
var allkeys, curKey = '[', len = 0, i = -1, entryK;
function formatKeys( entries ){
entryK = entries.length;
len += entries.length;
while (entryK--)
entries[entryK][0] = curKey+JSON.stringify(entries[entryK][0])+']';
return entries;
}
allkeys = formatKeys( Object.entries(obj) );
while (++i !== len)
if (typeof allkeys[i][1] === 'object' && allkeys[i][1] !== null){
curKey = allkeys[i][0] + '[';
Array.prototype.push.apply(
allkeys,
formatKeys( Object.entries(allkeys[i][1]) )
);
}
return allkeys;
}
次に、探している結果を出力するには、これを使用します。
function stringifyEntries(allkeys){
return allkeys.reduce(function(acc, x){
return acc+((acc&&'\n')+x[0])
}, '');
};
技術的なビットに興味がある場合は、これがどのように機能するかです。Object.entries
渡したオブジェクトの を取得し、obj
それらを array に入れることで機能しallkeys
ます。次に、 の最初からallkeys
最後まで、allkeys
エントリ値の 1 つがオブジェクトであることがわかった場合、そのエントリのキーを として取得し、その結果の配列を の最後にプッシュする前にcurKey
、独自の各エントリ キーの前に を付けます。次に、追加されたエントリの数をターゲットの長さに追加して、新しく追加されたキーも処理するようにします。curKey
allkeys
allkeys
たとえば、次の点に注意してください。
<script>
var object = {
aProperty: {
aSetting1: 1,
aSetting2: 2,
aSetting3: 3,
aSetting4: 4,
aSetting5: 5
},
bProperty: {
bSetting1: {
bPropertySubSetting : true
},
bSetting2: "bString"
},
cProperty: {
cSetting: "cString"
}
}
document.write(
'<pre>' + stringifyEntries( deepEntries(object) ) + '</pre>'
);
function deepEntries( obj ){//debugger;
'use-strict';
var allkeys, curKey = '[', len = 0, i = -1, entryK;
function formatKeys( entries ){
entryK = entries.length;
len += entries.length;
while (entryK--)
entries[entryK][0] = curKey+JSON.stringify(entries[entryK][0])+']';
return entries;
}
allkeys = formatKeys( Object.entries(obj) );
while (++i !== len)
if (typeof allkeys[i][1] === 'object' && allkeys[i][1] !== null){
curKey = allkeys[i][0] + '[';
Array.prototype.push.apply(
allkeys,
formatKeys( Object.entries(allkeys[i][1]) )
);
}
return allkeys;
}
function stringifyEntries(allkeys){
return allkeys.reduce(function(acc, x){
return acc+((acc&&'\n')+x[0])
}, '');
};
</script>
または、プロパティを持つオブジェクトではなく、プロパティのみが必要な場合は、次のようにフィルター処理して除外できます。
deepEntries(object).filter(function(x){return typeof x[1] !== 'object'});
例:
<script>
var object = {
aProperty: {
aSetting1: 1,
aSetting2: 2,
aSetting3: 3,
aSetting4: 4,
aSetting5: 5
},
bProperty: {
bSetting1: {
bPropertySubSetting : true
},
bSetting2: "bString"
},
cProperty: {
cSetting: "cString"
}
}
document.write('<pre>' + stringifyEntries(
deepEntries(object).filter(function(x){
return typeof x[1] !== 'object';
})
) + '</pre>');
function deepEntries( obj ){//debugger;
'use-strict';
var allkeys, curKey = '[', len = 0, i = -1, entryK;
function formatKeys( entries ){
entryK = entries.length;
len += entries.length;
while (entryK--)
entries[entryK][0] = curKey+JSON.stringify(entries[entryK][0])+']';
return entries;
}
allkeys = formatKeys( Object.entries(obj) );
while (++i !== len)
if (typeof allkeys[i][1] === 'object' && allkeys[i][1] !== null){
curKey = allkeys[i][0] + '[';
Array.prototype.push.apply(
allkeys,
formatKeys( Object.entries(allkeys[i][1]) )
);
}
return allkeys;
}
function stringifyEntries(allkeys){
return allkeys.reduce(function(acc, x){
return acc+((acc&&'\n')+x[0])
}, '');
};
</script>
ブラウザの互換性
上記のソリューションは IE では機能しません。Object.entries 関数を使用しているため、Edge でのみ機能します。IE9+ のサポートが必要な場合は、次のObject.entries
ポリフィルをコードに追加するだけです。私以外の何らかの理由で、実際に IE6+ のサポートが必要な場合は、Object.keys
andJSON.stringify
ポリフィルも必要になります (どちらもここにはリストされていないため、別の場所で見つけてください)。
if (!Object.entries)
Object.entries = function( obj ){
var ownProps = Object.keys( obj ),
i = ownProps.length,
resArray = new Array(i); // preallocate the Array
while (i--)
resArray[i] = [ownProps[i], obj[ownProps[i]]];
return resArray;
};