在嵌套对象(例如 Backbone.js集合)中搜索文本
Searching for text inside nested object (Backbone.js collection as example)
我有一个主干.js集合,我需要在其中进行全文搜索。我手头的工具如下:
Backbone.js, underscore.js, jQuery
对于那些不熟悉骨干网的人:
主干集合只是一个对象。在集合中有一个带有模型的数组。每个模型都有一个带有属性的数组。我必须在每个属性中搜索一个字符串。
我为此使用的代码是:
query = 'some user input';
query = $.trim(query);
query = query.replace(/ /gi, '|');
var pattern = new RegExp(query, "i");
// this.collection.forEach is the same as _.each
// only it get's the models from the collection
this.collection.forEach(function(model) {
var check = true;
_.each(model.attributes, function(attr){
if(pattern.test(attr) && check){
// Do something with the matched item
check = false;
}
}, this);
}, this);
也许我正在使用的工具之一有更好的方法来解决这个问题?
Backbone 将许多下划线方法扩展到Collection
类中,因此您可以摆脱其中的一些内容。 真的,您可能希望将其作为方法包含在集合本身上,然后我可能会使用一个很好的老式for
循环来查看这些键,特别是如果我想打破它。
// in Backbone.Collection.extend
search: function( query, callback ){
var pattern = new RegExp( $.trim( query ).replace( / /gi, '|' ), "i");
var collection = this;
collection.each(function(model) {
for( k in model.attributes ){
if( model.attributes.hasOwnProperty(k) && pattern.test(model.attributes[k]) ){
callback.call( collection, model, k );
break; // ends the for loop.
}
}
});
}
// later
collection.search('foo', function( model, attr ){
console.log('found foo in '+model.cid+' attribute '+attr);
});
也就是说,这只会返回集合中的第一场比赛。 您可能更喜欢以 [模型、属性] 对的形式返回结果数组的实现。
// in Backbone.Collection.extend
search: function( query, callback ){
var matches = [];
var pattern = new RegExp( $.trim( query ).replace( / /gi, '|' ), "i");
this.each(function(model) {
for( k in model.attributes ){
if( model.attributes.hasOwnProperty(k) && pattern.test(model.attributes[k]) ){
matches.push([model, k]);
}
}
});
callback.call( this, matches );
}
// later
collection.search('foo', function( matches ){
_.each(matches, function(match){
console.log('found foo in '+match[0].cid+' attribute '+match[1]);
});
});
或者,如果您想要一组匹配但不关心哪个属性匹配的模型,您可以使用filter
// in Backbone.Collection.extend
search: function( query, callback ){
var pattern = new RegExp( $.trim( query ).replace( / /gi, '|' ), "i");
callback.call( this, this.filter(function( model ){
for( k in model.attributes ){
if( model.attributes.hasOwnProperty(k) && pattern.test(k) )
return true;
}
}));
}
// later
collection.search('foo', function( matches ){
_.each(matches, function(match){
console.log('found foo in '+match[0].cid+' somewhere');
});
});
您的内在each
正在短路,因此您可以切换到_.any()
而不是_.each()
和标志组合; 一旦回调函数返回true
,any
就会停止迭代,并且还会委托给本机some
方法(如果可用)。
this.collection.each(function(model) {
_(model.attributes).any(function(attr, key) {
if(!pattern.test(attr))
return false;
// Do something with the matched item...
return true;
});
});
我还删除了参数this
上下文,因为您没有在任何地方使用this
,如果"做某事"需要它们,您可以将它们放回原处。
如果简单的正则表达式搜索不够好,您可以查看词干和集合的反向索引。
相关文章:
- 主干集合搜索url
- javascript按集合中的标题搜索节点并返回
- 骨干多集合全局搜索
- 如何使用nodejs在mongodb集合中搜索重音字符
- 如何在集合中的数组内搜索流星
- 快速搜索集合中的项目
- 在嵌套对象(例如 Backbone.js集合)中搜索文本
- 在主干中搜索集合
- 在集合中搜索具有类似属性和搜索参数的模型
- 在Meteor(MongoDB)中,按另一个集合中的值搜索一个集合
- 搜索条件表单和集合
- 从单个集合发布和订阅时没有搜索结果
- 在搜索mongo集合时,点符号参数
- MongoDB:我如何在同一数据库中搜索多个集合并返回混合结果集
- 在MongoDB集合中搜索并替换
- 流星集合现场搜索
- 如何搜索mongodb集合条目属性
- 使用Meteor.js将Foursquare API的搜索结果添加到新的Mongo集合中
- 使用backboneJS集合以任意顺序搜索单词
- 具有与字符串匹配的属性的模型的主干搜索集合