所以我有一个由一些json数据制作的表......
{
"AKH":{
"name": "Amonkhet",
"code": "AKH"
"cards": [
{
"artist": "Izzy",
"cmc": 3,
"colorIdentity": [
"W"
],
"colors": [
"White"
],
"id": "df3a6e0336684c901358f3ff53ec82ff5d7cdb9d",
"imageName": "gideon of the trials",
"layout": "normal",
"loyalty": 3,
"manaCost": "{1}{W}{W}",
"multiverseid": 426716,
"name": "Gideon of the Trials",
"number": "14",
"rarity": "Mythic Rare",
"subtypes": [
"Gideon"
],
"text": "+1: Until your next turn, prevent all damage target permanent would deal.\n0: Until end of turn, Gideon of the Trials becomes a 4/4 Human Soldier creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn.\n0: You get an emblem with \"As long as you control a Gideon planeswalker, you can't lose the game and your opponents can't win the game.\"",
"type": "Planeswalker — Gideon",
"types": [
"Planeswalker"
]
},
对于每张卡,Table行最终看起来像这样。目前我只将ID,卡名和法力消耗附加到每一行
<td><a href="#" onclick="showInfo(this.id)"
id="df3a6e0336684c901358f3ff53ec82ff5d7cdb9d">Gideon of the Trials</a></td>
现在我想搜索这些卡片。 (请记住,此列表中将有超过17,000种不同的卡片)我可以通过它找到这些东西......但是我有几个不同的问题...要么它找到它们全部但不隐藏其余的列表,或它隐藏整个列表,只显示找到的卡之一。
问题A ......我缺少什么才能使搜索工作正常?
$(document).on('change', 'input[type=checkbox]', function() {
var lis = $('.cardsRow')
$('input[type=checkbox]').filter(':checked').each(function(){
filterKeyB = $(this).attr('id')
filterKeyA = $(this).attr('name')
$.each(json, function(setCode, setListing) {
$.each(setListing.cards,function(cardNum, cardListing){
var x = Object.keys(cardListing)
var y = Object.keys(cardListing).map(function (key){
return cardListing[key]
})
for (i = 0; (i < x.length); i++) {
if(x[i] === filterKeyA){
if (y[i] instanceof Array){
var holder = y[i]
var valueArr =[]
for(var k = 0; k < holder.length; k++){
valueArr = holder.join('|').toLowerCase().split('|')
var foundIt = valueArr.includes(filterKeyB)
}
}else{
var stringy = y[i]
var stringyA= stringy.toLowerCase().replace(/\s/g, '')
if (stringyA === filterKeyB){
var foundIt = true
}
}
if(foundIt === true){
$winner = cardListing.name
for (k = 0; (k < lis.length); k++){
if (lis[k].innerText.indexOf($winner) != -1) {
$(lis[k]).show()
}
}
}
}
}
})
问题B ......因为您已经在这里...将可以搜索的数据附加到元素本身是否更好?也许只是搜索次数最多(比如姓名和法力)并且有更多高级查询会再次查看数据?
答案 0 :(得分:0)
我不明白为什么代码不起作用或甚至不起作用,看起来它引用了一些在样本中没有定义的函数。但我可以用一种非常简单/直观的方式与您分享过滤内容,我希望您觉得它很有用。
本机过滤器方法对于您尝试执行的操作非常有用,它需要一个将当前元素作为arg并返回true或false的回调,如果为true,则该元素包含在它生成的新数组中。
但是过滤器只需要一个函数,并且你有很多过滤器,所以让我们创建一个将许多过滤器Fns组合成一个fn的函数,这样你就可以一次性传递它们:
const combineFilters = (...fns) => val => fns.reduce((prev, curr) => prev || curr(val), false);
好的,如何将过滤器函数的名称存储为对象中的键,以便我们可以使用字符串引用它们?这样我们就可以给每个复选框一个与它们应该应用的过滤器函数名称相对应的ID,并使事情变得非常容易实现(和读取):
const filterFns = {
startsWithG(card) {
return card.name[0] === 'G';
},
//etc.
};
好的,是时候获取所有被点击的复选框的ID,然后将它们映射到一组函数中。
const filters = $('input[type=checkbox]')
.filter(':checked')
.map((e, i) => $(i).attr('id'))
.get()
.map(fnName => filterFns[fnName])
(假设相关数据存储在一个名为... data的var中。)我们可以使用combineFilters结合过滤器(Fns数组)激活所有相关过滤器,然后将生成的匹配对象数组映射到您选择的HTML。
const matches = data.cards
.filter(combineFilters(...filters))
.map(card => `<div>${card.name}</div>` );
然后是时候用你的比赛更新DOM了!
正如其他人所说,如果你需要对对象或数组进行更复杂的过滤,那么lodash库就是你的朋友!