如何在jQuery each循环中分组排序JSON数据实现议员下拉菜单
美国国会议员下拉菜单:分组(Sen/Rep)+ 字母排序实现方案
嘿,我来帮你搞定这个分组排序的下拉菜单!你现有的AJAX请求已经能成功获取议员数据了,接下来只需要完成数据分组、组内排序、分组渲染这三个核心步骤,就能实现你想要的效果。下面是具体思路和完整代码:
核心思路拆解
- 第一步:按议员类型分组
接口返回的每个议员对象里,terms数组的最后一项(当前任期)的type字段是sen(参议员)或rep(众议员),我们可以用这个字段把数据分成两个独立数组。 - 第二步:组内按字母排序
可以按议员的姓氏(name.last)进行字母排序,这样排序逻辑更清晰,符合用户的查找习惯。 - 第三步:用HTML的
<optgroup>实现分组下拉
HTML的<select>标签支持用<optgroup label="分组名称">来包裹同组选项,完美匹配你的分组需求。
完整代码实现
<select id="legislatorsSelect"></select> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $.ajax({ url:'https://theunitedstates.io/congress-legislators/legislators-current.json', dataType: 'json', type:'get', cache:false, success:function(data) { // 1. 分组:把数据分成参议员和众议员两个数组 const groupedData = data.reduce((groups, legislator) => { // 获取当前任期的议员类型(sen/rep) const currentTerm = legislator.terms[legislator.terms.length - 1]; const type = currentTerm.type === 'sen' ? 'Senators' : 'Representatives'; // 把当前议员加入对应分组 groups[type] = groups[type] || []; groups[type].push(legislator); return groups; }, {}); // 2. 对每个分组按姓氏字母排序 Object.keys(groupedData).forEach(groupName => { groupedData[groupName].sort((a, b) => { // 按姓氏的小写字母比较,避免大小写影响排序 const lastNameA = a.name.last.toLowerCase(); const lastNameB = b.name.last.toLowerCase(); if (lastNameA < lastNameB) return -1; if (lastNameA > lastNameB) return 1; return 0; }); }); // 3. 渲染分组下拉菜单 const $select = $('#legislatorsSelect'); // 遍历每个分组 Object.entries(groupedData).forEach(([groupName, legislators]) => { // 创建optgroup标签 const $optgroup = $('<optgroup>').attr('label', groupName); // 遍历分组内的议员,创建option标签 legislators.forEach(legislator => { const fullName = `${legislator.name.first} ${legislator.name.last}`; // 可以把议员的ID或其他标识存在value里,方便后续使用 const $option = $('<option>').val(legislator.id.govtrack).text(fullName); $optgroup.append($option); }); // 把分组添加到下拉菜单 $select.append($optgroup); }); }, error:function(xhr, status, error) { console.error('加载议员数据失败:', error); } }); </script>
关键代码解释
- 分组逻辑:用
Array.reduce()把原始数据归并成以分组名为键的对象,比循环push更简洁高效。如果想要更简洁的分组标签(比如直接显示'Sen'或'Rep'),只需要把分组名称的赋值改成const type = currentTerm.type.toUpperCase();即可。 - 排序逻辑:统一转成小写字母再比较,避免因为姓氏大小写(比如'McCain'和'mccain')导致排序混乱。
- 渲染逻辑:用jQuery的DOM创建方法动态生成
<optgroup>和<option>,保证代码的可维护性,同时把议员的govtrack ID存在value属性里,方便后续业务逻辑使用。
内容的提问来源于stack exchange,提问作者P Shudgins
相关产品推荐
相关产品推荐

