2012-05-05 14 views
5

Mam wejście JSON, które może przejść do dowolnej liczby poziomów.przechodzenie przez ciąg JSON do poziomów wewnętrznych za pomocą funkcji rekursywnej

daję próbkę wejściową

var d=getEntities({"Categories": 
{ 
"Facets": 
    [ 
    { 
    "count": 1, 
    "entity": "Company", 
    "Company": 
      [ 
      { 

      "entity": "Ford Motor Co", 

      "Ford_Motor_Co": 
       [ 
        { 
        "count": 1, 
        "entity": "Ford" 
        } 
       ] 
      } 
      ] 
    }, 
     { 
      "count": 4, 
      "entity": "Country", 
       "Country": [ 
        { 

         "entity": "Germany", 
         "Germany": [ 
           { 
            "count": 1, 
            "entity": "Germany" 
           } 
          ], 
         "currency": "Euro (EUR)" 
        }, 
        { 

         "entity": "Italy", 
         "Italy": [ 
           { 
            "count": 1, 
            "entity": "Italy" 
           } 
          ], 
         "currency": "Euro (EUR)" 
        }, 
        { 

         "entity": "Japan", 
          "Japan": [ 
          { 
            "count": 1, 
            "entity": "Japan" 
          } 
          ], 
         "currency": "Yen (JPY)" 
        }, 
        { 

         "entity": "South Korea", 
          "South_Korea": [ 
           { 
            "count": 1, 
            "entity": "South Korea" 
           } 
          ], 
         "currency": "Won (KRW)" 
        } 
       ] 
     }, 
     {"count": 5, 
       "entity": "Persons", 
       "Persons": [ 
        { 
         "count": 2, 
         "entity": "Dodge" 
        }, 
        { 
         "count": 1, 
         "entity": "Dodge Avenger" 
        }, 
        { 
         "count": 1, 
         "entity": "Major League" 
        }, 
        { 
         "count": 1, 
         "entity": "Sterling Heights" 
        } 
       ] 
     } 
    ] 

}}); 

chcę dodać wartość klucza „podmiot” na wszystkich poziomach do tablicy za pomocą rekurencji,

jestem w stanie zebrać dane od pierwszego poziomu, używając ciągu znaków:

<html> 
<head> 
<script src="jquery.js" type="text/javascript"></script> 
<script type="text/javascript" src="dataDumper.js"></script> 


<script type="text/javascript"> 

var testJSON = {"Categories": 
{ 
"Facets": 
    [ 
    { 
    "count": 1, 
    "entity": "Company", 
    "Company": 
      [ 
      { 

      "entity": "Ford Motor Co", 

      "Ford_Motor_Co": 
       [ 
        { 
        "count": 1, 
        "entity": "Ford" 
        } 
       ] 
      } 
      ] 
    }, 
     { 
      "count": 4, 
      "entity": "Country", 
       "Country": [ 
        { 

         "entity": "Germany", 
         "Germany": [ 
           { 
            "count": 1, 
            "entity": "Germany" 
           } 
          ], 
         "currency": "Euro (EUR)" 
        }, 
        { 

         "entity": "Italy", 
         "Italy": [ 
           { 
            "count": 1, 
            "entity": "Italy" 
           } 
          ], 
         "currency": "Euro (EUR)" 
        }, 
        { 

         "entity": "Japan", 
          "Japan": [ 
          { 
            "count": 1, 
            "entity": "Japan" 
          } 
          ], 
         "currency": "Yen (JPY)" 
        }, 
        { 

         "entity": "South Korea", 
          "South_Korea": [ 
           { 
            "count": 1, 
            "entity": "South Korea" 
           } 
          ], 
         "currency": "Won (KRW)" 
        } 
       ] 
     }, 
     {"count": 5, 
       "entity": "Persons", 
       "Persons": [ 
        { 
         "count": 2, 
         "entity": "Dodge" 
        }, 
        { 
         "count": 1, 
         "entity": "Dodge Avenger" 
        }, 
        { 
         "count": 1, 
         "entity": "Major League" 
        }, 
        { 
         "count": 1, 
         "entity": "Sterling Heights" 
        } 
       ] 
     } 
    ] 

}}; 

function scan(obj) 
{ 
    var k; 
    if (obj.hasOwnProperty('entity')) { 



     for (k in obj){ 
      if (obj.hasOwnProperty(k)){ 


       scan(obj[k]); 


      }     
      } 
    } 


    else{ 
     if(k=='entity') 
     { 
     alert(obj.entity); 
    } 
    } 


}; 

scan(testJSON); 



</script> 
</head> 

<body> 

</body> 

</html> 

Jak przejść do wewnętrznych poziomów łańcucha JSON za pomocą funkcji rekursywnych?

+0

Dont umieścić indziej, jeśli i umieścić alert przed wywołaniem do skanowania –

+0

Kciuk w górę !!! I wielkie dzięki! Naprawdę doceniam całą twoją pomoc. – user1371896

+0

@ ElRonnoco Eksperymentowałem z tą rzeczą i robisz wszystko na co chcesz dodać jednostki na różnych poziomach w tej samej tablicy .. tzn. Podmioty na poziomie 1 idą do jednej tablicy, poziom 2 do nxt i tak na .. – user1371896

Odpowiedz

15

Zrobiłem jsfiddle które przemierza każdy obiekt, tablica lub wartość przedmiotu JS jak tak ...

function scan(obj) 
{ 
    var k; 
    if (obj instanceof Object) { 
     for (k in obj){ 
      if (obj.hasOwnProperty(k)){ 
       //recursive call to scan property 
       scan(obj[k]); 
      }     
     } 
    } else { 
     //not an Object so obj[k] here is a value 
    }; 

}; 

mam żadnego błędu rekursji (w Chrome). Czy możesz tego użyć, aby zrobić to, co chcesz?

Jeśli chcesz sprawdzić, czy obiekt jest korzystać z tablicą if (obj instanceof Array)

Aby sprawdzić, czy obiekt ma „podmiot” użytkowania nieruchomości if (obj.hasOwnProperty('entity'))

dodać (lub modyfikować istniejące) „podmiot” własność używać obj.entity = value lub obj['entity'] = value

+1

Odpowiedziałem na ten temat na moim iPhonie, więc gdyby ktoś mógł naprawić moje formatowanie, byłbym bardzo wdzięczny !!! –

+0

pokazuje błąd, jeśli jest zdefiniowany dla If (h.hasOwnProperty (k)). – user1371896

+0

Ah może być nowy, aby przetestować dla "if (h instanceof object)" przed wejściem do pętli. –

1
(function recur(obj) { 
    Object.keys(obj).forEach(function(prop) { 
     // Check if the property is an object 
     if (({}).toString.apply(prop) === '[object Object]') { 
      // If it is, recall this function 
      recur(prop); 
     } 
    }); 
}()); 

Nie dodałem twojej logiki, ale masz pomysł, jak rekursywnie przemierzać twój obiekt.

+0

Proszę, daj mi to ... spytaj o opinię aftr, że .. – user1371896

+0

Jak dodać wartość podobiektów tutaj dla powyższego przykładu? – user1371896

+0

Co? Nie rozumiem twojego komentarza. –

1

Say I mają strukturę tak:

var aObject = { 
    items: [], 
    children: {} 
} 

Dzieci to tablica asocjacyjna zawierająca więcej obiektów aObject. Więc może to wyglądać tak:

var aObject = { 
    items: [], 
    children: { 
     "subgroup1": { 
      items: [], 
      children: {} 
     }, 
     "subgroup2": { 
      items: [], 
      children: {} 
     } 
    } 
} 

mam element, który zawiera szereg podgrup:

["subgroup1", "subgroup1a"] 

Każda podgrupa jest „lokalizacja”. Rzecz musi być umieszczony pod adresem:

aObject.children[array[0]].children[array[1]].items 

Na każdym poziomie, musimy sprawdzić, czy dzieci [tablica [i]] istnieje, a jeśli nie, utwórz go. Nie możesz po prostu napisać aObject.children [array [0]]. Children [array [1]]. Items.push (item) ponieważ children [array [0]] może jeszcze nie istnieć, a otrzymamy błąd.

Można to rozwiązać za pomocą rekursji! (angularjs)

function recursive(aLevel, aItem, aArray, aIndex){ 
    var lLevel = aLevel; 

    // If we have reached the end of the array 
    if (aIndex === aArray.length){ 
     // Insert 
     aLevel.items.push(aItem); 
    } else { 

     // If the subgroup doesn't exist, create it 
     if (typeof aLevel.children[aArray[aIndex]] === 'undefined'){ 
      aLevel.children[aArray[aIndex]] = { 
       items: [], 
       children: {} 
      }; 
     } 

     // Move into 
     recursive(aLevel.children[aArray[aIndex]], aItem, aArray, aIndex+1); 
    } 
} 

aObject = { 
    items: [], 
    children: {}, 
} 

angular.forEach(items, function(item, i){ 
    var location = item.location; 

    if (location.length == 0){ 
     aObject.items.push(item); 
    } else { 
     recursive(aObject, item, location, 0); 
    } 
}); 

Ostateczna aObject będzie wyglądać następująco:

var aObject = { 
    items: [], 
    children: { 
     "subgroup1": { 
      items: [], 
      children: { 
       "subgroup1a": { 
        items: [item], 
        children: {} 
       } 
      } 
     }, 
     "subgroup2": { 
      items: [], 
      children: {} 
     } 
    } 
} 
1

Oto funkcja, która używam często. Łatwo można go modyfikować, wykonując wiele zadań rekursywnych. Na przykład, jeśli dodasz flagę za kaucją, możesz szybko uzyskać stos lub dodać funkcję wywołania zwrotnego, dzięki czemu stanie się jeszcze bardziej ogólna.W każdym razie to moje 2 centy

var recursiveObjMap = (function(){ 
    var stack = []; 
    var result = []; 
    // var bail = false; 
    return function map(data, key){ 
    if (!$.isArray(data) && !$.isPlainObject(data)) { 
     result.push(data); 
     return false 
    } 

    $.each(data, function(i, v){ 
     if (key) stack.push(key); 
     map(v, i); 
     stack.pop(); 
    }); 
    return result; 
    }; 
})(); 

recursiveObjMap({a:'b',c:{d:{e:"f"}}}) // ['b', 'f'] 
Powiązane problemy