news 2026/3/27 21:59:55

Mapbox GL JS 核心表达式:`in` 包含判断完全教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Mapbox GL JS 核心表达式:`in` 包含判断完全教程

in是 Mapbox GL JS 表达式系统中高频使用的包含关系判断工具,核心作用是:判断一个值是否存在于数组中(数组包含),或一个子字符串是否存在于目标字符串中(字符串包含)。相比==多条件组合(如any + 多个 ==),in能大幅简化代码;同时需注意字符串字面量的literal包裹规则,避免类型解析错误。本文将从核心概念、语法、实战场景、进阶用法到常见误区,全面讲解in表达式的使用。

一、in表达式核心概念

1.1 核心定义

in表达式支持两种核心判断场景,返回值均为布尔值(true/false):

  • 数组包含:判断第一个参数(关键词)是否是第二个参数(数组)的元素(支持布尔值、字符串、数字类型,需类型完全匹配);
  • 字符串包含:判断第一个参数(子字符串)是否是第二个参数(目标字符串)的子串(区分大小写、重音,需注意字面量包裹规则)。

1.2 语法格式

官方定义的语法简洁,需严格区分参数类型:

// 场景1:数组包含(input 为数组)["in",keyword:InputType,input:array<InputType>]:boolean// 场景2:字符串包含(input 为字符串)["in",keyword:string,input:string]:boolean

关键说明:

  • InputType:支持布尔值(true/false)、字符串(string)、数字(number),关键词与数组元素/目标字符串类型必须一致
  • 字面量包裹规则:当第二个参数(input)和第三个参数(实际应为第二个参数,语法中 input 是第二个参数)均为字符串字面量时,至少一个需用["literal", 值]包裹(避免 Mapbox 类型系统误解为其他逻辑);
  • 短路求值:数组包含判断中,找到匹配元素后立即终止遍历;字符串包含判断基于底层字符串查找逻辑,效率高于手动遍历。

1.3 与any + ==的对比

数组包含场景中,inany + 多个 ==的简化版,两者逻辑等价但in更简洁高效:

// 冗余写法:any + 多个 ==["any",["==",["get","type"],"restaurant"],["==",["get","type"],"coffee"]]// 简洁写法:in + 数组["in",["get","type"],["literal",["restaurant","coffee"]]]

二、前置准备

所有示例需先初始化 Mapbox 地图(替换为自己的 Access Token,从 Mapbox 官网 注册获取):

<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>Mapbox in 表达式示例</title><scriptsrc="https://api.mapbox.com/mapbox-gl-js/v3.4.0/mapbox-gl.js"></script><linkhref="https://api.mapbox.com/mapbox-gl-js/v3.4.0/mapbox-gl.css"rel="stylesheet"><style>body{margin:0;padding:0;}#map{width:100vw;height:100vh;}.controls{position:absolute;top:20px;left:20px;background:#fff;padding:12px;border-radius:8px;box-shadow:0 2px 8pxrgba(0,0,0,0.1);}button{margin:5px;padding:6px 12px;cursor:pointer;}</style></head><body><divid="map"></div><divclass="controls"><buttonid="filterType">筛选餐饮类(数组包含)</button><buttonid="filterName">筛选名称含"北京"(字符串包含)</button><buttonid="reset">重置</button></div><script>mapboxgl.accessToken='你的 Mapbox Access Token';// 替换为自己的 Tokenconstmap=newmapboxgl.Map({container:'map',style:'mapbox://styles/mapbox/streets-v12',center:[116.4074,39.9042],// 北京坐标zoom:14});</script></body></html>

三、基础使用场景

3.1 场景1:数组包含——批量筛选要素类型

in最常用的场景是批量判断要素属性是否属于目标集合(如筛选餐饮类 POI、特定行政区划等),替代冗余的any + 多个 ==

示例:筛选类型为restaurant(餐厅)、coffee(咖啡)、grocery(便利店)的 POI:

map.on('load',()=>{// 模拟多类型 POI 数据constpoiData={type:'FeatureCollection',features:[{type:'Feature',geometry:{type:'Point',coordinates:[116.4074,39.9042]},properties:{type:'restaurant',name:'北京饭店'}},{type:'Feature',geometry:{type:'Point',coordinates:[116.4084,39.9052]},properties:{type:'coffee',name:'星巴克'}},{type:'Feature',geometry:{type:'Point',coordinates:[116.4094,39.9062]},properties:{type:'grocery',name:'7-11'}},{type:'Feature',geometry:{type:'Point',coordinates:[116.4104,39.9072]},properties:{type:'park',name:'城市公园'}},{type:'Feature',geometry:{type:'Point',coordinates:[116.4114,39.9082]},properties:{type:'hotel',name:'快捷酒店'}}]};// 添加数据源map.addSource('poi-source',{type:'geojson',data:poiData});// 添加图层:默认显示所有 POImap.addLayer({id:'poi-layer',type:'circle',source:'poi-source',paint:{'circle-radius':8,'circle-color':'#999'// 灰色默认样式},filter:['all']});// 按钮1:数组包含判断——筛选餐饮类 POIdocument.getElementById('filterType').onclick=()=>{map.setFilter('poi-layer',['in',// 核心表达式:判断 type 是否在数组中['get','type'],// 关键词:要素的 type 属性['literal',['restaurant','coffee','grocery']]// 目标数组(必须用 literal 包裹)]);// 高亮筛选结果map.setPaintProperty('poi-layer','circle-color','#ff6347');map.setPaintProperty('poi-layer','circle-radius',12);};});

关键说明:

  • 目标数组['restaurant', 'coffee', 'grocery']必须用["literal", ...]包裹,因为它是字符串字面量数组,避免 Mapbox 误解析;
  • 若要素type属于数组中的任意一个值,即返回true,实现批量筛选,比any + 三个 ==简洁得多。

3.2 场景2:字符串包含——关键词筛选要素名称

in可判断要素属性字符串中是否包含目标子串(如筛选名称含“北京”“公园”的要素),适用于关键词搜索场景。

示例:筛选名称中包含“北京”或“公园”的要素:

// 延续上述示例,添加按钮2的逻辑document.getElementById('filterName').onclick=()=>{map.setFilter('poi-layer',['any',// 多个字符串包含判断(满足其一即可)['in','北京',// 子字符串(关键词)['get','name']// 目标字符串:要素的 name 属性],['in','公园',// 子字符串(关键词)['get','name']// 目标字符串]]);// 高亮筛选结果map.setPaintProperty('poi-layer','circle-color','#4169e1');map.setPaintProperty('poi-layer','circle-radius',12);};// 重置按钮逻辑document.getElementById('reset').onclick=()=>{map.setFilter('poi-layer',['all']);map.setPaintProperty('poi-layer','circle-color','#999');map.setPaintProperty('poi-layer','circle-radius',8);};

关键说明:

  • 此处无需用literal包裹,因为目标字符串是['get', 'name'](动态属性值),而非字符串字面量;
  • 字符串包含判断区分大小写和重音(如“北京”≠“beijing”,“café”≠“cafe”),如需忽略,需结合collator表达式(见进阶用法)。

四、进阶用法

4.1 进阶1:字符串包含 + Collator 忽略大小写/重音

默认字符串包含判断是严格匹配,结合collator可实现本地化适配(如忽略大小写、重音),需将关键词或目标字符串用["to-string", ...]转换后配合使用。

示例:忽略大小写筛选名称含“beijing”的要素(匹配“北京饭店”“Beijing Hotel”):

map.on('load',()=>{// 模拟含大小写的名称数据constnameData={type:'FeatureCollection',features:[{type:'Feature',geometry:{type:'Point',coordinates:[116.4074,39.9042]},properties:{name:'北京饭店'}},{type:'Feature',geometry:{type:'Point',coordinates:[116.4084,39.9052]},properties:{name:'Beijing Hotel'}},{type:'Feature',geometry:{type:'Point',coordinates:[116.4094,39.9062]},properties:{name:'上海大厦'}}]};map.addSource('name-source',{type:'geojson',data:nameData});map.addLayer({id:'name-layer',type:'circle',source:'name-source',paint:{'circle-radius':10,'circle-color':'#999'},filter:['all']});// 忽略大小写筛选map.setFilter('name-layer',['in',['to-string',['literal','beijing']],// 关键词转字符串['to-string',['get','name']],// 目标字符串转字符串{locale:'en-US',case-sensitive:false}// 忽略大小写]);map.setPaintProperty('name-layer','circle-color','#32cd32');});

4.2 进阶2:in+case实现多条件样式控制

结合case表达式,可根据要素属性是否属于不同数组/包含不同子串,动态设置样式。

示例:餐饮类 POI 用红色,公园类用绿色,名称含“酒店”的用蓝色:

map.addLayer({id:'style-layer',type:'circle',source:'poi-source',paint:{'circle-radius':10,'circle-color':['case',// 条件1:餐饮类(in 数组判断)['in',['get','type'],['literal',['restaurant','coffee','grocery']]],'#ff6347',// 条件2:公园类(in 数组判断)['in',['get','type'],['literal',['park','greenbelt']]],'#32cd32',// 条件3:名称含“酒店”(in 字符串判断)['in','酒店',['get','name']],'#4169e1',// 默认颜色'#999']}});

4.3 进阶3:动态数组/字符串判断(结合用户输入)

in支持动态参数,可结合用户输入(如搜索框关键词)生成目标数组/子串,实现交互性筛选。

示例:用户输入关键词后,筛选名称包含关键词的 POI:

<!-- 添加搜索框到 controls 中 --><divclass="controls"><inputtype="text"id="searchInput"placeholder="输入名称关键词"><buttonid="searchBtn">搜索</button></div><script>// 搜索按钮逻辑document.getElementById('searchBtn').onclick=()=>{constkeyword=document.getElementById('searchInput').value.trim();if(!keyword)return;map.setFilter('poi-layer',['in',keyword,// 动态关键词(用户输入)['get','name']]);map.setPaintProperty('poi-layer','circle-color','#ff4500');};</script>

五、常见误区与注意事项

5.1 字符串字面量未用literal包裹(致命错误)

当第二个和第三个参数均为字符串字面量时,必须至少一个用["literal", ...]包裹,否则 Mapbox 类型系统会误解,导致解析错误:

// 错误:两个均为字符串字面量,未用 literal 包裹["in","a","ab"]// 正确:至少一个用 literal 包裹["in",["literal","a"],"ab"]["in","a",["literal","ab"]]["in",["literal","a"],["literal","ab"]]

5.2 数组元素类型与关键词类型不匹配

in是严格类型判断,数组元素类型与关键词类型必须一致,否则返回false

// 错误:关键词是数字 123,数组元素是字符串 "123"["in",123,["literal",["123","456"]]]// 正确:类型一致(均为数字或均为字符串)["in",123,["literal",[123,456]]]["in",["to-string",123],["literal",["123","456"]]]// 数字转字符串

5.3 混淆数组包含与字符串包含的参数顺序

in的参数顺序是「关键词在前,目标在后」,与 JavaScript 的Array.includes()一致,但与字符串String.includes()相反,需注意:

// Mapbox in:关键词(子串)在前,目标(数组/字符串)在后["in","a",["literal",["a","b"]]]// 数组包含:正确["in","a",["literal","ab"]]// 字符串包含:正确// 错误:参数顺序颠倒(返回 false)["in",["literal",["a","b"]],"a"]

5.4 空数组/空字符串的判断结果

  • 空数组:["in", 任意值, ["literal", []]]始终返回false
  • 空字符串:["in", 任意非空字符串, ["literal", ""]]始终返回false["in", "", ["literal", "ab"]]返回true(空字符串是任何字符串的子串)。

5.5 用in替代any + 多个 ==时的性能优势

当需要判断一个属性是否属于多个固定值时,in的性能远高于any + 多个 ==,尤其是数组元素较多时(如 10 个以上),因为in是单次遍历判断,而any需多次表达式求值。

六、完整实战示例:多场景包含判断交互

整合数组包含、字符串包含、动态搜索功能,实现“餐饮类筛选 + 名称关键词搜索 + 忽略大小写匹配”的完整交互:

<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>Mapbox in 表达式完整实战</title><scriptsrc="https://api.mapbox.com/mapbox-gl-js/v3.4.0/mapbox-gl.js"></script><linkhref="https://api.mapbox.com/mapbox-gl-js/v3.4.0/mapbox-gl.css"rel="stylesheet"><style>body{margin:0;padding:0;}#map{width:100vw;height:100vh;}.controls{position:absolute;top:20px;left:20px;background:#fff;padding:15px;border-radius:8px;box-shadow:0 2px 10pxrgba(0,0,0,0.1);}h4{margin:0 0 10px 0;}input{margin:5px 0;padding:6px;width:200px;}button{margin:5px;padding:6px 12px;cursor:pointer;}</style></head><body><divid="map"></div><divclass="controls"><h4>POI 筛选工具</h4><inputtype="text"id="searchInput"placeholder="输入名称关键词(支持忽略大小写)"><buttonid="searchBtn">关键词搜索</button><br><buttonid="filterFood">筛选餐饮类(餐厅/咖啡/便利店)</button><buttonid="filterPark">筛选公园类(公园/绿地)</button><br><buttonid="reset">重置</button></div><script>mapboxgl.accessToken='你的 Mapbox Access Token';constmap=newmapboxgl.Map({container:'map',style:'mapbox://styles/mapbox/streets-v12',center:[116.4074,39.9042],zoom:14});map.on('load',()=>{// 1. 模拟综合 POI 数据constpoiData={type:'FeatureCollection',features:[{type:'Feature',geometry:{type:'Point',coordinates:[116.4074,39.9042]},properties:{type:'restaurant',name:'北京饭店'}},{type:'Feature',geometry:{type:'Point',coordinates:[116.4080,39.9050]},properties:{type:'coffee',name:'Starbucks 星巴克'}},{type:'Feature',geometry:{type:'Point',coordinates:[116.4090,39.9060]},properties:{type:'grocery',name:'7-11 便利店'}},{type:'Feature',geometry:{type:'Point',coordinates:[116.4100,39.9070]},properties:{type:'park',name:'城市公园'}},{type:'Feature',geometry:{type:'Point',coordinates:[116.4110,39.9080]},properties:{type:'greenbelt',name:'街边绿地'}},{type:'Feature',geometry:{type:'Point',coordinates:[116.4120,39.9090]},properties:{type:'hotel',name:'Beijing 快捷酒店'}}]};// 2. 添加数据源map.addSource('poi-source',{type:'geojson',data:poiData});// 3. 添加图层(动态样式)map.addLayer({id:'poi-layer',type:'circle',source:'poi-source',paint:{'circle-radius':10,'circle-color':'#999','circle-stroke-width':2,'circle-stroke-color':'#fff'},filter:['all']});// 4. 关键词搜索(忽略大小写)document.getElementById('searchBtn').onclick=()=>{constkeyword=document.getElementById('searchInput').value.trim().toLowerCase();if(!keyword)return;map.setFilter('poi-layer',['in',['to-string',['literal',keyword]],['to-string',['get','name']],{locale:'en-US',case-sensitive:false}]);map.setPaintProperty('poi-layer','circle-color','#ff4500');};// 5. 筛选餐饮类(数组包含)document.getElementById('filterFood').onclick=()=>{map.setFilter('poi-layer',['in',['get','type'],['literal',['restaurant','coffee','grocery']]]);map.setPaintProperty('poi-layer','circle-color','#ff6347');};// 6. 筛选公园类(数组包含)document.getElementById('filterPark').onclick=()=>{map.setFilter('poi-layer',['in',['get','type'],['literal',['park','greenbelt']]]);map.setPaintProperty('poi-layer','circle-color','#32cd32');};// 7. 重置document.getElementById('reset').onclick=()=>{map.setFilter('poi-layer',['all']);map.setPaintProperty('poi-layer','circle-color','#999');document.getElementById('searchInput').value='';};});</script></body></html>

七、总结

in表达式是 Mapbox 实现批量筛选、关键词搜索的核心工具,核心价值体现在:

  1. 简洁性:替代any + 多个 ==,大幅简化数组包含判断代码;
  2. 高效性:底层优化的查找逻辑,性能优于手动遍历判断;
  3. 多功能性:同时支持数组包含和字符串包含,覆盖多场景需求;
  4. 扩展性:可结合collator/case/动态参数,实现本地化适配、样式控制、交互搜索。

使用时需重点注意:

  • 字符串字面量数组必须用["literal", ...]包裹,避免解析错误;
  • 关键词与目标数组/字符串的类型必须一致,否则返回false
  • 字符串包含默认区分大小写/重音,需忽略时结合collator表达式;
  • 动态场景(如用户输入)中,直接传入变量作为关键词/目标,无需literal包裹。

掌握in表达式后,可大幅提升 Mapbox 地图的筛选效率和交互体验,尤其适合 POI 分类筛选、关键词搜索等高频场景。结合之前学习的==/all/any表达式,可实现更复杂的复合逻辑(如["all", ["in", A, B], ["any", C, D]])。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/27 19:46:26

大数据采集中的调度策略:定时采集与实时采集对比

选定时还是实时&#xff1f;大数据采集中的调度策略深度对比与实践指南 一、引言&#xff1a;大数据采集的“调度困境” 你是否遇到过这样的问题&#xff1f; 想做实时用户推荐&#xff0c;却因为数据采集延迟&#xff0c;导致推荐结果总是慢半拍&#xff1f;想做离线日报表&am…

作者头像 李华
网站建设 2026/3/23 4:13:12

滑台模组的安装

一 安装与调试安装平台与固定确保安装平台具有足够刚度与稳定性&#xff0c;以减小运行中的抖动与共振&#xff1b;尽量增大模组底座与平台的接触面积。安装台面平整度建议不低于0.05 mm/500 mm&#xff0c;高精密场合建议小于0.02 mm/500 mm。安装前清理平台异物、毛刺。固定螺…

作者头像 李华
网站建设 2026/3/27 9:41:50

35 岁后被淘汰?实施和运维的 “青春饭” 传言,该戳破了

35 岁后被淘汰&#xff1f;实施和运维的 “青春饭” 传言&#xff0c;该戳破了 在IT行业&#xff0c;“35岁危机”像一道悬在头顶的达摩克利斯之剑&#xff0c;让不少从业者焦虑&#xff1a;自己的岗位到底是不是“吃青春饭”&#xff1f;其中&#xff0c;实施工程师和运维工程…

作者头像 李华
网站建设 2026/3/24 11:32:07

Vulhub漏洞靶场搭建(非常详细),零基础入门到精通,看这一篇就够了

文章目录 简介 环境安装 安装Docker安装Docker-Compose安装VulhubDocker加速 靶场使用物理机访问容器启动环境复现步骤前台GetShell其它问题汇总 简介 Vulhub是一个面向大众的开源漏洞靶场&#xff0c;无需docker知识&#xff0c;简单执行两条命令即可编译、运行一个完整的漏…

作者头像 李华
网站建设 2026/3/11 17:25:37

必藏!10种大模型训练与微调方法原理,AI产品经理程序员入门必备

在大模型落地热潮中&#xff0c;无论是AI产品经理规划技术路径&#xff0c;还是程序员动手实操&#xff0c;都绕不开模型训练与微调这一核心环节。选对微调方法&#xff0c;能让70B大模型在单卡24GB显存上跑起来&#xff0c;还能让领域任务准确率提升10%以上。本文整理了10种核…

作者头像 李华