我写过两个我认为对我正在做的工作非常有用的Array方法。以Ruby的数组方法为模型,这里是我的find和find_all方法。只是想我会把它们扔给社区并得到一些反馈。我是JS编程的新手,所以我可能没有使用足够的防御机制,也许还有一些优化。有什么想法吗?
Array.prototype.find = function(attrs){
// If an object wasn't passed in return false, maybe throw format exception?
// or do primitive type search, but that's not really useful as you're passing in the very value you're looking for
if (typeof attrs != 'object'){
return false;
}else{
for(var i=0; i < this.length; i++){
if (typeof this[i] != 'object'){
return false;
}else{
var match = true;
// Loop through all attributes of the parameters object and test for existence and match
for(item in attrs){
match = match && (this[i][item] && (this[i][item] === attrs[item]) );
}
if(match){
return this[i];
}
}
}
// default return if no items found
return false;
}
};
// find_all behaves similarly to find only returns all matched objects
// See ruby's find_all method on arrays
Array.prototype.find_all = function(attrs){
// If an object wasn't passed in return false, maybe throw format exception?
// or do primitive type search, but that's not really useful as you're passing in the very value you're looking for
if (typeof attrs != 'object'){
return false;
}else{
var valid_items = [];
for(var i=0; i < this.length; i++){
if (typeof this[i] != 'object'){
return false;
}else{
var match = true;
// Loop through all attributes of the parameters object and test for existence and match
for(item in attrs){
match = match && (this[i][item] && (this[i][item] === attrs[item]) );
}
if(match){
valid_items.push(this[i]);
}
}
}
return valid_items;
}
}
一些例子:
var a={id:1,parent_id:2}
var b={id:2,parent_id:3}
var c={id:3,parent_id:2}
var arr = [a,b,c]
arr.find({parent_id:2})
// Object id: 1 parent_id: 2
arr.find_all({parent_id:2})
// [Object id: 1 parent_id: 2, Object id: 3 parent_id: 2 ]
答案 0 :(得分:3)
您的函数会修改原型Array。有些图书馆觉得这没关系(原型)。其他人反对(jQuery)这种全局修改。
请参阅Prototype网站上的this page。你会明白为什么他们认为修改数组原型是可以的,但前提是你没有使用for ... in循环迭代[编辑:数组(你是对的,你“没有这样做”]。
我实际上更喜欢jQuery的决定,因为你希望你的代码可以重用并且与其他代码一起玩得很好。
另外看一下find算法,如果this [i]具有比attrs更多的属性,只要它们具有共同匹配的属性,它将返回true,但它将是false。
要进行完整的比较,您还必须检查长度,但是对象没有长度属性,因此您必须在一个循环中计算此[i]并分别对其进行长度计算。
编辑:看看你的例子。看起来你知道这两个对象并不完全相同。您确定在搜索{id:1,parent_id:2}
}时希望找到{parent_id:2
吗?看起来更像是你在询问obj param是否等于对象数组中任何对象的属性子集。你想称之为“发现”吗?这真的是你想要的吗?我认为发现只有在完全相同或者称之为其他东西时才会返回。
编辑2:另一个想法。我肯定会find_all
调用find
作为其基本机制。这样你就不会重复你的代码,并且你更可能保证找到匹配的东西,find_all会匹配。您不希望在其基础搜索算法之间出现差异。虽然要这样做,你可能不得不重构一下,找回对象的索引而不是对象,这应该不是问题。
答案 1 :(得分:1)
而不是“typeof attrs!='object'”,更常见的是:
if (attrs == null){
return false;
}
(您也可以使用“if(attrs == undefined)”)。
答案 2 :(得分:1)
除了其他答案所说的,这里有一些关于你的代码的非JS特定事项:
当你有一个返回的if子句时,你不需要else。
if(foo) {
return false;
}
//other code here
这将使您的代码更具可读性,因为会有更少的缩进/级别来跟踪您的内心。
您的函数不遵循通常的JavaScript命名约定。如果你看看任何JS内置方法,他们使用camelCase而不是underscore_separated。遵循语言惯例总是一个好主意。
答案 3 :(得分:0)
这些对您来说可能是有用的功能,但我会重新考虑将它们添加到Array原型中 - 它们似乎不够通用,因为它们只查找对象属性值。我只是将它们用作实用程序函数(传入数组)或将它们添加到某个实用程序类中。当我想到一个数组查找方法时,我想到了更像这里的例子:http://www.hunlock.com/blogs/Mastering_Javascript_Arrays(但后来我不熟悉Ruby的版本)。