2015-01-21 1 views
-1

예를 들어, 임의의 심도의 중첩을 가진 다른 객체를 포함 할 수있는 JavaScript 객체가 있습니다. 재귀를 사용하지 않고이 객체의 모든 요소를 ​​순회 할 수 있습니까?자바 스크립트에서 비회원 방식으로 객체를 트래버스 할 수 있습니까?

그렇다면 데이터 구조가 비 반복적 반복을 사용하여 순회하도록하기위한 최소 요구 사항은 무엇입니까?

+6

스택이있는 루프로 재귀를 변경할 수 있습니다. – SLaks

+0

for in 루프는 답이 될 수 있습니다 : for (var i in obj) {....} – Blauharley

+0

솔루션을 향해 나를 가리켜 주셔서 감사합니다 :) –

답변

5

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

중첩 된 배열에서도 작동합니다. 큰. – aBe

0

이 순환 참조에 대한 기본 형식에 대한 지원뿐만 아니라 (배열 포함) 복잡한 유형뿐만 아니라, 보호를 필요로한다. 다음은 임의의 객체를 순회하고 문자열 화해야하는 샘플 재귀 적 함수의 예입니다.

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 
} 
관련 문제