2012-02-29 273 views
1

我有一个JavaScript对象,这可能是这样的过滤器的JavaScript对象

{ 
    "users": [{ 
     "id": "52", 
     "name": "User name one", 
     "profile": "student", 
     "statusId": 1 
    },... 

我想给定一组参数来修改该对象的属性。基本上我想要一个新的对象的属性可以匹配一组约束 - 一个滤镜对象 - 这种形式(空滤):

var userFilter = { 
     id : "", 
     name: "", 
     profile : "", 
     state : "" 
    }; 

我见过的Array.prototype.filter,但找不出一个干净和通用方式来使用过滤器的所有属性。我尝试过使用javascript字符串来连接所有过滤器并使用eval(),但我不喜欢这种方法。任何建议?

由于提前, 问候

回答

3

您可以使用这样的事情来比较两个JavaScript对象:

// returns true if "obj" contains "other" as a subset 
contains = function(obj, other) { 
    return Object.keys(other).every(function(key) { 
     return other[key] == obj[key]; 
    }); 
} 

例如,contains(users[0], {profile: 'student'})回报true

一旦我们有了这个,剩下的很简单:

userFilter = { ...criteria... } 
results = users.filter(function(item) { return contains(item, userFilter) }) 

注意这并AND匹配,也就是说,如果过滤器为{state:5, profile:'student'},它发现有两个状态= 5和外形=学生记录。替代地做OR匹配,在上面的代码中用some()代替every()

按照您评论,上述功能可以通过添加一个比较功能作为一个参数被概括:

contains = function(obj, other, compare) { 
    return Object.keys(other).every(function(key) { 
     return compare ? compare(key, obj[key], other[key]) 
      : obj[key] == other[key]; 
    }); 
} 

比较函数接受键,对象值和过滤器值和应该返回真或假。例如:

user = { 
     "id": "52", 
     "name": "Foo Bar" 
} 

// this uses the default "equals" comparison and fails 
contains(user, { name: "Foo" }); 

// this uses a custom "indexOf" comparison and succeeds 
contains(user, { name: "Foo" }, function(key, val, flt) { 
    return val.indexOf(flt) >= 0; 
}); 
+0

好的方法。我无法测试同等的对象,即。对于id我必须找到一个完全匹配,但名称应该是'obj'包含'other'的单词。我想我必须有2'包含'功能 – jose 2012-02-29 15:47:53

+1

@ jose:看到更新... – georg 2012-02-29 16:01:33

+0

非常感谢 – jose 2012-02-29 16:09:40