JavaScript includes()方法匹配异常:无法正确定位目标歌曲
问题说明
我在JSON中存储了两首歌曲:"Yağmur"和"Yağmurlar",需要根据包含blah blah yağmurlar、blah blah yağmur的文本,或是精确值yağmur、yağmurlar进行搜索。但使用includes()方法时,总是匹配到"Yağmur"歌曲,而非期望的目标歌曲。例如:
- 输入:
şebo yağmurlar - 实际结果:返回"Yağmur"歌曲
- 期望结果:返回"Yağmurlar"歌曲
相关代码
var needle = "şebo yağmurlar" var haystack = { "items": [{ "song": "Yağmurlar", "artist": "blah" }, { "song": "Yağmur", "artist": "blah" }] } var found = haystack.items.find( item => needle.includes(item.song.toLocaleLowerCase('tr-TR'))) || needle.includes(item.artist.toLocaleLowerCase('tr-TR'))
问题原因
Array.find()方法会返回第一个满足条件的元素。由于"Yağmur"是"Yağmurlar"的子串,当将歌曲名转为小写后,yağmur会被输入文本şebo yağmurlar包含,因此遍历到"Yağmur"这一项时就直接返回了,不会继续检查后面的"Yağmurlar"。
解决方案
方案1:先按歌曲名长度倒序排序
先将歌曲列表按名称长度从长到短排序,让更长的字符串(比如"Yağmurlar")优先被匹配,这样find()会先找到符合要求的目标项:
var needle = "şebo yağmurlar" var needleLower = needle.toLocaleLowerCase('tr-TR'); var haystack = { "items": [{ "song": "Yağmurlar", "artist": "blah" }, { "song": "Yağmur", "artist": "blah" }] } // 按歌曲名长度倒序排序,长字符串优先 var sortedItems = [...haystack.items].sort((a, b) => b.song.length - a.song.length); var found = sortedItems.find(item => { const songLower = item.song.toLocaleLowerCase('tr-TR'); const artistLower = item.artist.toLocaleLowerCase('tr-TR'); return needleLower.includes(songLower) || needleLower.includes(artistLower); }); console.log(found); // 输出:{ song: 'Yağmurlar', artist: 'blah' }
方案2:优化匹配逻辑,优先选中更长匹配项
如果不想排序,可以遍历所有元素,记录匹配到的最长字符串对应的歌曲:
var needle = "şebo yağmurlar" var needleLower = needle.toLocaleLowerCase('tr-TR'); var haystack = { "items": [{ "song": "Yağmurlar", "artist": "blah" }, { "song": "Yağmur", "artist": "blah" }] } var found = null; var maxMatchLength = 0; haystack.items.forEach(item => { const songLower = item.song.toLocaleLowerCase('tr-TR'); const artistLower = item.artist.toLocaleLowerCase('tr-TR'); // 检查歌曲名是否被包含 if (needleLower.includes(songLower)) { if (songLower.length > maxMatchLength) { maxMatchLength = songLower.length; found = item; } } // 检查歌手名是否被包含 else if (needleLower.includes(artistLower)) { if (artistLower.length > maxMatchLength) { maxMatchLength = artistLower.length; found = item; } } }); console.log(found); // 输出:{ song: 'Yağmurlar', artist: 'blah' }
内容的提问来源于stack exchange,提问作者Volkan
相关产品推荐
相关产品推荐

