2012-05-24 30 views
7

Tôi chỉ không phải là một nhà khoa học máy tính tốt, đủ để con số này ra bởi bản thân mình :(Chức năng đệ quy để tạo đối tượng JSON phân cấp?

Tôi có một API mà trả về phản hồi JSON mà trông như thế này:

// call to /api/get/200 
{ id : 200, name : 'France', childNode: [ id: 400, id: 500] } 
// call to /api/get/400 
{ id : 400, name : 'Paris', childNode: [ id: 882, id: 417] } 
// call to /api/get/500 
{ id : 500, name : 'Lyon', childNode: [ id: 998, id: 104] } 
// etc 

Tôi muốn phân tích nó đệ quy và xây dựng một đối tượng JSON thứ bậc mà trông giống như sau:

{ id: 200, 
    name: 'France', 
    children: [ 
    { id: 400, 
     name: 'Paris', 
     children: [...] 
    }, 
    { id: 500, 
     name: 'Lyon', 
     children: [...] 
    } 
    ], 
} 

cho đến nay, tôi có điều này, mà không phân tích tất cả các nút của cây, nhưng không lưu nó vào một đối tượng JSON Làm thế nào tôi có thể. mở rộng này để lưu nó vào JS ON đối tượng?

hierarchy = {} 
def get_child_nodes(node_id): 
    request = urllib2.Request(ROOT_URL + node_id) 
    response = json.loads(urllib2.urlopen(request).read()) 
    for childnode in response['childNode']: 
     temp_obj = {} 
     temp_obj['id'] = childnode['id'] 
     temp_obj['name'] = childnode['name'] 
     children = get_child_nodes(temp_obj['id']) 
    // How to save temp_obj into the hierarchy? 
get_child_nodes(ROOT_NODE) 

Đây không phải là bài tập về nhà, nhưng có lẽ tôi cần phải làm một số bài tập về nhà để có được tốt hơn tại giải quyết loại vấn đề :(Cảm ơn bạn đã giúp đỡ nào.

+0

được trẻ em cho trẻ em có chứa id hay phản đối? – wong2

+0

Một danh sách các đối tượng, do đó, hệ thống phân cấp tiếp tục tất cả các con đường xuống các nút lá. – flossfan

+0

thử simplejson.dumps(). – fanlix

Trả lời

6
def get_node(node_id): 
    request = urllib2.Request(ROOT_URL + node_id) 
    response = json.loads(urllib2.urlopen(request).read()) 
    temp_obj = {} 
    temp_obj['id'] = response['id'] 
    temp_obj['name'] = response['name'] 
    temp_obj['children'] = [get_node(child['id']) for child in response['childNode']] 
    return temp_obj 

hierarchy = get_node(ROOT_NODE) 
1

Bạn sẽ không quay trở lại bất cứ điều gì từ mỗi .. gọi đến hàm đệ quy Vì vậy, nó có vẻ như bạn chỉ muốn thêm mỗi temp_obj từ điển vào một danh sách trên mỗi lần lặp của vòng lặp, và gửi lại sau khi kết thúc vòng lặp Cái gì như:

def get_child_nodes(node_id): 
    request = urllib2.Request(ROOT_URL + node_id) 
    response = json.loads(urllib2.urlopen(request).read()) 
    nodes = [] 
    for childnode in response['childNode']: 
     temp_obj = {} 
     temp_obj['id'] = childnode['id'] 
     temp_obj['name'] = childnode['name'] 
     temp_obj['children'] = get_child_nodes(temp_obj['id']) 
     nodes.append(temp_obj) 
    return nodes 

my_json_obj = json.dumps(get_child_nodes(ROOT_ID)) 

(BTW, hãy cẩn thận khi trộn các tab và các khoảng trắng vì Python không rất tha thứ cho điều đó. Tốt nhất để chỉ dính vào không gian.)

+0

Và làm cách nào để bạn tạo phân cấp mong muốn từ danh sách đó? Mục đích là để có một bộ từ điển lồng nhau mà sau đó sẽ là 'json.dumps()' ed. –

+0

Và mã của tôi không được cung cấp như thế nào? Mỗi đệ quy tạo thành từ điển riêng của nó, sau đó được trả về cho phụ huynh. –

+0

Xin lỗi Daniel. Tôi đã đọc sai cả cấu trúc mong muốn và mã của bạn. –

-1

Tuyên bố từ chối trách nhiệm: Tôi không biết json là gì, vì vậy bạn có thể phải phân loại cách viết chính xác bằng ngôn ngữ của bạn: p. Nếu mã giả trong ví dụ của tôi quá giả, hãy hỏi thêm chi tiết.

Bạn cần trả lại thứ gì đó ở đâu đó. Nếu bạn không bao giờ trả lại một cái gì đó trong cuộc gọi đệ quy của bạn, bạn không thể có được tham chiếu đến các đối tượng mới của bạn và lưu trữ nó trong các đối tượng bạn có nơi bạn gọi là đệ quy.

def getChildNodes (node) returns [array of childNodes] 
    data = getData(fromServer(forThisNode)) 
    new childNodes array 
    for child in data : 
     new temp_obj 
     temp_obj.stores(child.interestingStuff) 
     for grandchild in getChildNodes(child) : 
      temp_obj.arrayOfchildren.append(grandchild) 
     array.append(temp_obj) 
    return array 

Hoặc, bạn có thể sử dụng trình lặp thay vì trả lại nếu ngôn ngữ của bạn hỗ trợ.

2

Bạn có thể sử dụng này (một phiên bản nhỏ gọn hơn và dễ đọc)

def get_child_nodes(node_id): 
    request = urllib2.Request(ROOT_URL + node_id) 
    response = json.loads(urllib2.urlopen(request).read()) 
    return { 
     "id":response['id'], 
     "name":response['name'], 
     "children":map(lambda childId: get_child_nodes(childId), response['childNode']) 
    } 

get_child_nodes(ROOT_NODE) 
1

tôi đã cùng một vấn đề chiều nay, và kết thúc rejigging một số mã tôi tìm thấy trực tuyến.

Tôi đã tải mã lên Github (https://github.com/abmohan/objectjson) cũng như PyPi (https://pypi.python.org/pypi/objectjson/0.1) dưới tên gói 'objectjson'. Ở đây nó là dưới đây, cũng như:

(objectjson.py)

import json 

class ObjectJSON: 

    def __init__(self, json_data): 

    self.json_data = "" 

    if isinstance(json_data, str): 
     json_data = json.loads(json_data) 
     self.json_data = json_data 

    elif isinstance(json_data, dict): 
     self.json_data = json_data 

    def __getattr__(self, key): 
    if key in self.json_data: 
     if isinstance(self.json_data[key], (list, dict)): 
     return ObjectJSON(self.json_data[key]) 
     else: 
     return self.json_data[key] 
    else: 
     raise Exception('There is no json_data[\'{key}\'].'.format(key=key)) 

    def __repr__(self): 
    out = self.__dict__ 
    return '%r' % (out['json_data']) 

Sample Cách sử dụng

from objectjson import ObjectJSON 

json_str = '{ "test": {"a":1,"b": {"c":3} } }' 

json_obj = ObjectJSON(json_str) 

print(json_obj)   # {'test': {'b': {'c': 3}, 'a': 1}} 
print(json_obj.test)  # {'b': {'c': 3}, 'a': 1} 
print(json_obj.test.a) # 1 
print(json_obj.test.b.c) # 3 
Các vấn đề liên quan