2015-04-20 62 views
1

我有一個對象的數組:擴展對象的數組,在Javascript

[{id: 1, parentId: 0, title: 'root'}, 
{id: 2, parentId: 1, title: 'home'}, 
{id: 3, parentId: 1, title: 'level 1'}, 
{id: 4, parentId: 2, title: 'level 2'}] 

我想在這個陣列上創建功能,這樣我就可以用這樣的方法調用:

var node = library.findById(4); 

,也以擴展實際的對象本身,所以我可以創建如下功能:

var parent = node.parent(); 
var grandparent = parent.parent(); 
var children = grandparent.children(); 

到目前爲止我這樣做是這樣的:

// server.js 
var library = require('./library').init(nodes); 

// library.js 
'use strict'; 
var _ = require('lodash'), 
    Node = require('./node'); 

function objectifyNodes(lib, nodes) { 
    var a = []; 
    nodes.forEach(function (n) { 
    a.push(new Node(lib, n)); 
    }); 
    return a; 
} 

function Library(nodes) { 
    this.nodes = objectifyNodes(this, nodes); 
} 

Library.prototype.findById = function(id) { 
    var x = _.find(this.nodes, function(node) {return node.id === id; }); 
    if (x) { return x; } 
    return null; 
}; 

module.exports = { 
    init: function(nodes) { 
     var lib = new Library(nodes); 
     return lib; 
    } 
}; 

// node.js 
'use strict'; 
var _ = require('lodash'); 

function Node(lib, properties) { 
    _.extend(this, properties); 
    this.lib = lib; 
} 

Node.prototype.parent = function() { 
    return this.lib.findById(this.parentId); 
}; 

Node.prototype.children = function() { 
    return this.lib.findByParentId(this.id); 
}; 

module.exports = Node; 

鑑於它們可能有1000個節點,這是一個合理的實現方法嗎?有沒有更好的模式可以用於解決方案?

+0

我不認爲成千上萬的節點應該是一個問題,但它取決於你的服務器有多少內存,還有什麼你要求它存儲在內存中,還有其他一些變量。如果速度變慢,您可能需要切換到數據庫驅動的模型。 –

+0

就性能而言,我可以建議的一件事就是將節點以'id's作爲關鍵字保存在一個對象中。然後,您只需通過'library.nodes [id]'來訪問某個節點。當然,如果你不關心節點的排序,這纔有意義。 – basilikum

+0

@ basilikum - 或創建id:object的索引對象,只要這些ID是唯一的。它甚至可以是'{id:{node:obj,parent:obj,grandParent:obj,...},id {...}} ;-) – RobG

回答

1

您應該按照它們的id s(我假設它是唯一的)存儲節點,以便您可以快速訪問它們。使用數組(對於不太稀疏的整數ID),對象(默認)或Map(在最近的node.js版本中)。

function objectifyNodes(lib, nodes) { 
    var a = {}; 
    nodes.forEach(function (n) { 
    a[n.id] = new Node(lib, n); 
    }); 
    return a; 
} 


Library.prototype.findById = function(id) { 
    return this.nodes[id] || null; 
}; 

這樣,每次都不必篩選整個數組。你的庫的其餘部分看起來很好。

+0

謝謝,我可能會保留它,因爲我們可能會在更多功能中添加像Children()這樣的庫,它將根據parentId進行過濾。 我主要關心的是先調用objectifyNodes是否是最好的方法,聽起來好像這樣可行 –

+0

那麼,你仍然可以過濾對象... – Bergi