Bokeh中MultiChoice组件CustomJS过滤:如何实现精确匹配而非包含匹配?
解决Bokeh MultiChoice组件精确匹配过滤的问题
你的问题核心在于containsAny函数的逻辑搞反了,且采用了包含匹配的判断逻辑,导致只要当前Strain字符串包含选中的子串就会被过滤出来。要实现精确匹配,只需检查当前Strain值是否完全存在于选中数组中即可。
修改方案一:修正containsAny函数
把原函数的判断逻辑改成检查当前项是否在选中数组中,替换后的代码如下:
var s1 = source.data; var selected = multi_choice.value; var new_data= {}; new_data['Acidity']=[]; new_data['Chlorides']=[]; new_data['Density']=[]; new_data['Sulfates']=[]; new_data['Rating']=[]; // 修正后的精确匹配函数:判断当前项是否在选中数组里 function containsAny(selectedItems, currentItem) { // 使用indexOf判断是否存在(兼容旧环境),也可以用selectedItems.includes(currentItem)更直观 return selectedItems.indexOf(currentItem) !== -1; } for (var i = 0; i < s1['Strain'].length; i++) { // 参数顺序:第一个是选中的数组,第二个是当前要判断的Strain项 if (containsAny(selected, s1['Strain'][i])) { new_data['Acidity'].push(s1['Strain'][i]) new_data['Chlorides'].push(s1['THC_AVG'][i]) new_data['Density'].push(s1['CBD'][i]) new_data['Sulfates'].push(s1['IND'][i]) new_data['Rating'].push(s1['Rating'][i]) } } table_source.data = new_data
修改方案二:去掉冗余函数,直接判断
如果觉得函数多余,可以直接在循环里做精确匹配判断,代码更简洁:
var s1 = source.data; var selected = multi_choice.value; var new_data= {}; new_data['Acidity']=[]; new_data['Chlorides']=[]; new_data['Density']=[]; new_data['Sulfates']=[]; new_data['Rating']=[]; for (var i = 0; i < s1['Strain'].length; i++) { // 直接判断当前Strain是否在选中数组里,精确匹配 if (selected.indexOf(s1['Strain'][i]) !== -1) { new_data['Acidity'].push(s1['Strain'][i]) new_data['Chlorides'].push(s1['THC_AVG'][i]) new_data['Density'].push(s1['CBD'][i]) new_data['Sulfates'].push(s1['IND'][i]) new_data['Rating'].push(s1['Rating'][i]) } } table_source.data = new_data
关键说明
- 原函数逻辑是检查选中项是否被当前Strain包含,会导致部分匹配(比如选中"ABC",Strain是"ABCD"也会被选中);修正后是检查当前Strain是否完全等于选中数组里的某一项,实现精确匹配。
- 如果运行环境支持ES6语法,也可以用
selected.includes(s1['Strain'][i])替代indexOf,代码可读性更高,效果完全一致。
内容的提问来源于stack exchange,提问作者mg520
相关产品推荐
相关产品推荐

