javascript - 如何更改搜索功能以接受任何单词组合
问题描述
当我尝试搜索产品的标题时,它只会显示确切的单词、一个单词或连续单词的组合的结果。
例如,如果我正在尝试查找产品,如果我尝试搜索,blue flying car
产品不会blue car
显示。基本上我希望我的搜索被修复以接受不同的组合。我怎样才能做到这一点?
var item_xlsx = './assets/data/products.xlsx';
var all_items = [];
var all_cats = [];
var subcats = [];
var catQuery = '';
var subCatQuery = '';
var titleQuery = '';
function load_data() {
// get query parameters
catQuery = get_param('cat');
subCatQuery = get_param('subcat');
titleQuery = get_param('searchtext');
$('#searchtext').val(titleQuery);
$('#cat').val(catQuery);
fetch(item_xlsx).then(function (res) {
if (!res.ok) throw new Error("fetch failed");
return res.arrayBuffer();
}).then(function (ab) {
var data = new Uint8Array(ab);
var workbook = XLSX.read(data, { type: "array" });
var first_sheet_name = workbook.SheetNames[0];
var worksheet = workbook.Sheets[first_sheet_name];
all_items = XLSX.utils.sheet_to_json(worksheet, { raw: true });
populate_cats();
populate_subcats(catQuery);
render_category_form();
render_search_form(catQuery, titleQuery, all_items);
render_search_summary(catQuery, titleQuery, all_items);
render_search_results(catQuery, titleQuery, all_items);
});
}
function get_param(name) {
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
var results = regex.exec(location.search);
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
}
/* Filter items and render search results */
function render_search_results(cat, query, items) {
let results = all_items.filter(function (value, index, self) { // filter by cat
if (!catQuery || catQuery === "") {
return true;
} else {
return value.cat == catQuery;
}
}).filter(function (value, index, self) { // filter by subcat
if (!subCatQuery || subCatQuery === "") {
return true;
} else {
return value.subcat == subCatQuery;
}
}).filter(function (value, index, self) { // filter by query
if (!titleQuery || titleQuery === "") {
return true;
} else {
var regex = new RegExp(titleQuery, "i");
return value.name.search(regex) != -1 || value.audience.search(regex) != -1;
}
})
解决方案
尝试过滤搜索查询中的每个单词 - 这样结果将仅包含这些包含所有搜索单词的项目。
测试的搜索功能示例:
// setting the test array values
var all_items = ['abba the cure metall', 'abba the best songs', 'blue car abba', 'moose egipt sand sun abba', 'sunny day the company', 'abba songs', 'egiptian culture songs', 'blue sunny skies', 'singing songs when sky is blue', 'in a car with abba', 'in a car with moose', 'moose is blue', 'matallic moose', 'best songs while driving a car', 'metall skies of egipt', 'sing a song with abba'];
// converting the array into arr of objects similar to those in your code
$.each(all_items, function(i,v){
all_items[i]= {name: v, audience: ''};
});
// display all elements
$.each(all_items, function(i,v){ $('#namesDiv').append( $('<div/>').text(v.name) ); });
//
$('form').submit(function(e){
e.preventDefault();
// setting the test query from input element
var titleQuery = $('#search').val();
// filter by query
var queryParts = titleQuery.split(/[^\w]+/g); // split the keywords
var result_items = $.extend(true, [], all_items); // copy all items to result array
for(var i=0; i<queryParts.length; i++){ // iterate through keywords
var regex = new RegExp(queryParts[i], "i");
// check if current keyword is a part of name if not remove the item from result array
result_items = result_items.filter(function (value, index, self) {
return regex.test(value.name) || regex.test(value.audience);
});
}
// show search results in console
console.clear();
console.info('found '+result_items.length+' items:');
console.log(JSON.stringify(result_items));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form><input id='search' value="song abba"><button type="submit">search</button></form>
<div id="namesDiv" style="padding-bottom:5em;"></div>
嵌套在您的函数中时,上面的搜索代码将如下所示:
/* Filter items and render search results */
function render_search_results(cat, query, items) {
var results = all_items.filter(function (value, index, self) { // filter by cat
if (!catQuery || catQuery === "") {
return true;
} else {
return value.cat == catQuery;
}
}).filter(function (value, index, self) { // filter by subcat
if (!subCatQuery || subCatQuery === "") {
return true;
} else {
return value.subcat == subCatQuery;
}
});
if (titleQuery) { // filter by query
var queryParts = titleQuery.split(/[^\w]+/g); // split the keywords from query
for(var i=0; i<queryParts.length; i++){ // iterate through keywords
var regex = new RegExp(queryParts[i], "i");
// check if current keyword is a part of name or audience if not remove the item from results array
results = results.filter(function (value, index, self) {
return regex.test(value.name) || regex.test(value.audience);
});
}
}
如果您只需要搜索整个单词 - 只需使用正则表达式 - 上述解决方案包括子字符串匹配。
推荐阅读
- java - 如果用户调整框架大小,如何扩展/缩小 glcanvas (Jogl)?
- react-native - 从反应原生的推送通知中打开应用程序时如何重定向到屏幕
- keras - 如何为 Keras fit 生成器正确调用和设置参数
- reactjs - 在尝试 git push heroku master 和 yarn 时出现错误
- reactjs - 如何将 col-sm-3 列的数组转换为每行 4 列的行?
- c# - C#如何将列表添加到字典中
- reactjs - Chrome 内置的“油漆闪烁”和 Chrome 的 react 开发工具的“高亮更新”之间的重新渲染行为不同
- ruby - 在数组中搜索值
- c - DMA 传输比 CPU 传输花费更多时间
- sql - 如何将表示 EPOCH 时间的整数转换为 Athena (Presto) 中的时间戳?