2015-04-20 59 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