Javascript 使用关键字搜索json

Javascript 使用关键字搜索json,javascript,json,Javascript,Json,我需要一些人帮我做一件小事。我必须创建一个通用搜索输入,通过json的音乐号码进行搜索。用户必须能够在搜索栏中键入专辑/曲目或艺术家,然后才能得到结果。和其他搜索栏一样。只有这一个搜索基于按键而不是提交按钮 我遇到的问题是,我收到了一个包含5000多个条目的大型JSON文件。我的搜索栏必须能够根据部分键入的“关键字”识别条目。例如,如果我想搜索麦当娜并输入“麦当娜”,我应该已经在搜索结果中找到了一些麦当娜(当然也有可能找到其他标题中有麦当娜的条目) 对不起,我的语法不好,但我尽我所能把情况解释得

我需要一些人帮我做一件小事。我必须创建一个通用搜索输入,通过json的音乐号码进行搜索。用户必须能够在搜索栏中键入专辑/曲目或艺术家,然后才能得到结果。和其他搜索栏一样。只有这一个搜索基于按键而不是提交按钮

我遇到的问题是,我收到了一个包含5000多个条目的大型JSON文件。我的搜索栏必须能够根据部分键入的“关键字”识别条目。例如,如果我想搜索麦当娜并输入“麦当娜”,我应该已经在搜索结果中找到了一些麦当娜(当然也有可能找到其他标题中有麦当娜的条目)

对不起,我的语法不好,但我尽我所能把情况解释得尽可能好

现在开始提问!我正在绞尽脑汁的是如何循环通过json文件来搜索这些关键字。这是我收到的json的一小部分:

{
"1": {
    "track": "Dani California",
    "artist": "Red Hot Chili Peppers",
    "album": "Stadium Arcadium"
},
"2": {
    "track": "Tell me baby",
    "artist": "Red Hot Chili Peppers",
    "album": "Stadium Arcadium"
},
"3": {
    "track": "Snow (Hey Oh)",
    "artist": "Red Hot Chili Peppers",
    "album": "Stadium Arcadium"
}}
通常,我会创建一个类似以下内容的函数:

for(var i = 0; i < data.length; i++){
if(data[i].album == 'red hot'){
    console.log(data[i].album)
}}
for(变量i=0;i
但在本例中,我希望循环使用json,查找包含搜索值的实体,并将其保存到对象以供以后使用

有可能一次完成这一切吗?因此,立即检查艺术家/标题/专辑,还是创建一个小过滤器更好


如果我的解释有不清楚的地方,请见见我,知道我尽了最大努力让自己尽可能清楚

我不认为搜索5000个条目会导致性能问题。 查看此代码,当您调用
search('text')

var data=JSON.parse('JSON data HERE')//数据集
var search_fields=['track'、'artist'、'album']//要在数据集中搜索的关键字段
功能搜索(关键字){
if(关键字.length搜索“forn”)
返回1//低相关性
其他的
返回0//没有匹配项,没有相关性
}
函数比较衰减(a,b){
返回b.相关性-a.相关性
}

由于它不是数组,除非将对象转换为数组,否则不能使用
数组.prototype.filter()
。您可以在每次获得新的Json时执行此操作,无需在每次搜索时执行此操作

var myArray = [];
for(var elementName in data) //We iterate over the Object to get the names of the nested objects
    myArray.push(data[elementName]); //We get the objects of the json and push them inside our array.
然后可以使用.filter来过滤数据,我建议使用regex:

var userQuery = 'Mado' //user input
var myRegex = new RegExp('.*' + userQuery + '.*','gi'); //We create a new regular expression, this one tests if the text is contained within a string.

var filteredArray = myArray.filter(function(item){
    //We test each element of the object to see if one string matches the regexp.
    return (myRegex.test(item.track) || myRegex.test(item.artist) || myRegex.test(item.album))

}); 
filteredArray
应该是您需要的json元素


以下是我经常用于过滤功能的模式。一些要点是:

  • 始终生成包含可筛选值的附加字符串的索引属性。例如,如果可以过滤“track”、“artist”和“album”的值,则将它们的值合并到一个字符串中,并将该字符串作为属性之一添加到原始对象中

    这有助于使用
    indexOf
    快速搜索,而无需在筛选时遍历每个对象。由于不再需要这些迭代和额外的
    属性数*对象数
    比较,因此它显著提高了性能。在您的情况下,每个过滤器操作将节省大约10k比较和15k迭代

  • 如果筛选操作不区分大小写,请在添加值以生成索引时使用
    toLowerCase
    。它还可以避免每次调用筛选器时执行许多
    toLowerCase
    操作

  • 始终创建对象数组,而不是具有对象属性的对象。我没有关于这是否会提高性能的具体统计数据,但它提供了一些数组方法,如
    array.filter
    array.sort
    ,您可以利用这些方法来提高用户体验。我在代码段中没有这样做,但是在准备数据时,您可以非常轻松地做到这一点

  • var数据={
    "1": {
    “轨道”:“Dani California”,
    “艺术家”:“红辣椒”,
    “专辑”:“体育场拱廊”
    },
    "2": {
    “轨迹”:“告诉我宝贝”,
    “艺术家”:“红辣椒”,
    “专辑”:“体育场拱廊”
    },
    "3": {
    “轨道”:“雪(嘿哦)”,
    “艺术家”:“红辣椒”,
    “专辑”:“体育场拱廊”
    }};
    //一次性活动!
    //为每个对象建立搜索索引。
    用于(数据中的var prop){
    if(data.hasOwnProperty(prop)){
    var指数=”;
    var项目=数据[prop];
    //迭代每个对象并通过附加每个属性的值来构建索引。
    对于(项目中的var attr){
    if(项目hasOwnProperty(属性)){
    //注意:不同的值由散列分隔,因为散列不太可能进入搜索查询。
    索引=索引+项目[attr]+“#”;
    }
    }
    //将索引属性插入到对象中。
    //还请注意toLowerCase,它允许稍后进行case-instive搜索。
    item.index=index.toLowerCase();
    }
    }
    console.log(“准备好的数据:”,数据);
    //过滤过程。
    var key=“Sn”;
    var keyLowerCase=key.toLowerCase();
    //迭代对象并比较索引prpoerty以与搜索字符串匹配。
    变量filteredData=[];
    用于(数据中的var prop){
    if(data.hasOwnProperty(prop)){
    var项目=数据[prop];
    if(item.index.indexOf(keyLowerCase)>=0){
    过滤数据推送(项目);
    }
    }
    }
    
    log(“过滤数据:”,过滤数据)当你说JSON时,它是一个JSON字符串吗?您确实可以解析它,然后对它进行过滤。@NisargShah条目太多了。使用keyup,搜索整个文档并返回False将花费很长时间。我也有同样的问题。如果JSON很小,您可以使用jQuery的keyup和循环遍历JSON条目(通过ajax调用),并使用.equals将它们与来自的输入文本条目进行比较html@Alan是的,我知道这一点。我构建了一个0.3秒的短超时
    var userQuery = 'Mado' //user input
    var myRegex = new RegExp('.*' + userQuery + '.*','gi'); //We create a new regular expression, this one tests if the text is contained within a string.
    
    var filteredArray = myArray.filter(function(item){
        //We test each element of the object to see if one string matches the regexp.
        return (myRegex.test(item.track) || myRegex.test(item.artist) || myRegex.test(item.album))
    
    });