예를 들어, 임의의 심도의 중첩을 가진 다른 객체를 포함 할 수있는 JavaScript 객체가 있습니다. 재귀를 사용하지 않고이 객체의 모든 요소를 순회 할 수 있습니까?자바 스크립트에서 비회원 방식으로 객체를 트래버스 할 수 있습니까?
그렇다면 데이터 구조가 비 반복적 반복을 사용하여 순회하도록하기위한 최소 요구 사항은 무엇입니까?
예를 들어, 임의의 심도의 중첩을 가진 다른 객체를 포함 할 수있는 JavaScript 객체가 있습니다. 재귀를 사용하지 않고이 객체의 모든 요소를 순회 할 수 있습니까?자바 스크립트에서 비회원 방식으로 객체를 트래버스 할 수 있습니까?
그렇다면 데이터 구조가 비 반복적 반복을 사용하여 순회하도록하기위한 최소 요구 사항은 무엇입니까?
SLaks 위의 모든 재귀는 스택이있는 루프로 표시 될 수 있습니다. 그래서 잠시 생각을 한 후 나는 다음 해결책을했다 : 임의의 객체를 순회
var myobj = {
one: "hello",
two: "world",
three: {
one: 1,
two: 2,
three: 4,
four: {
one: true,
two: false
}
},
four: "!"
};
function traverse(obj) {
var stack = [];
stack.push(obj);
while (stack.length) {
for (var j in stack[0]) {
if (typeof stack[0][j] === 'object') {
stack.push(stack[0][j]);
} else {
console.log('%s: %s', j, stack[0][j]);
}
}
stack.shift();
}
}
traverse(myobj);
중첩 된 배열에서도 작동합니다. 큰. – aBe
이 순환 참조에 대한 기본 형식에 대한 지원뿐만 아니라 (배열 포함) 복잡한 유형뿐만 아니라, 보호를 필요로한다. 다음은 임의의 객체를 순회하고 문자열 화해야하는 샘플 재귀 적 함수의 예입니다.
function FlatStringify(Arg)
{
var ToString = '', ArgObject, Resume, nStartIndex, Stack = [], Processed = []
do
{
if(Array.isArray(Arg))
{
var nIndex, nLen = Arg.length
if(Resume)
{
nStartIndex = Resume[1] + 1
ArgObject = Resume[2]
Resume = undefined
if(nStartIndex < nLen)
{
ToString += ', '
}
}
else
{
if(Processed.indexOf(ArgObject ? ArgObject : Arg) >= 0)
{
ToString += '{ <cyclic>'
nStartIndex = nLen
}
else
{
Processed.push(ArgObject ? ArgObject : Arg)
nStartIndex = 0
ToString += '{'
}
}
nIndex = nStartIndex
if(nIndex < nLen)
{
// Save our Array and loop position
Stack.push([ Arg, nIndex, ArgObject ])
// Restore Object Context if any!
if(ArgObject)
{
ToString += ' ' + Arg[ nIndex ] + ': '
Arg = ArgObject[ Arg[ nIndex ] ]
}
else
{
ToString += ' '
Arg = Arg[ nIndex ]
}
nIndex++
}
if(nIndex >= nLen)
{
ToString += ' }'
ArgObject = undefined
}
else
{
// Skip to the while(...)
continue
}
}
else if(typeof Arg === 'object')
{
if(Arg == null)
{
ToString += 'null'
}
else
{
ArgObject = Arg
Arg = Object.keys(ArgObject)
continue
}
}
else if(typeof Arg === 'string')
{
ToString += "'" + Arg + "'"
}
else if(typeof Arg === 'function')
{
ToString += 'function ' + Arg.name + '(){...}'
}
else if(typeof Arg === 'number')
{
ToString += Arg
}
else if(typeof Arg === 'boolean')
{
ToString += Arg
}
else
{
//console.log(typeof Arg)
ToString += typeof Arg//String(Arg)
}
if(Stack.length)
{
//console.log('Resuming: ' + Stack.length + '(' + nLoops + ')')
Resume = Stack.pop()
Arg = Resume[0]
}
}
while(Resume || ArgObject || Stack.length)
return ToString
}
스택이있는 루프로 재귀를 변경할 수 있습니다. – SLaks
for in 루프는 답이 될 수 있습니다 : for (var i in obj) {....} – Blauharley
솔루션을 향해 나를 가리켜 주셔서 감사합니다 :) –