如何依据sort_based_on_this_order数组排序JSON数组attachments?
按指定顺序对JSON数组排序的解决方案
我需要将名为attachments的JSON数组,按照sort_based_on_this_order数组指定的顺序排序。其中sort_based_on_this_order的元素对应attachments中每个对象filename字段里的13位数字后缀。
相关数组定义如下:
var sort_based_on_this_order = ['1666432801510', '1666434048280', '1666433926644', '1666434169913', '1666433101760', '1666434194815', '1666432849037', '1666432764144', '1666432044571', '1666432742444'] var attachments = [ { "download_small_url": "https://kf.kobotoolbox.org/api/v2/assets/ajDWYWQoe9Gw6WAnK8H4fG/data/194338021/attachments/82978911/", "mimetype": "image/jpeg", "filename": "deploymentsmaster/attachments/a46854ceb37c4e55b4a2c5ea565c4ebf/04ac3197-7d0f-4301-bbaf-68daaee2b1a8/1666433926644.jpg", "instance": 194338021, "xform": 740320, "id": 82978911 }, { "download_small_url": "https://kf.kobotoolbox.org/api/v2/assets/ajDWYWQoe9Gw6WAnK8H4fG/data/194338021/attachments/82978910/", "mimetype": "image/jpeg", "filename": "deploymentsmaster/attachments/a46854ceb37c4e55b4a2c5ea565c4ebf/04ac3197-7d0f-4301-bbaf-68daaee2b1a8/1666434169913.jpg", "instance": 194338021, "xform": 740320, "id": 82978910 }, { "download_small_url": "https://kf.kobotoolbox.org/api/v2/assets/ajDWYWQoe9Gw6WAnK8H4fG/data/194338021/attachments/82978909/", "mimetype": "image/jpeg", "filename": "deploymentsmaster/attachments/a46854ceb37c4e55b4a2c5ea565c4ebf/04ac3197-7d0f-4301-bbaf-68daaee2b1a8/1666434048280.jpg", "instance": 194338021, "xform": 740320, "id": 82978909 }, { "download_small_url": "https://kf.kobotoolbox.org/api/v2/assets/ajDWYWQoe9Gw6WAnK8H4fG/data/194338021/attachments/82978907/", "mimetype": "image/jpeg", "filename": "deploymentsmaster/attachments/a46854ceb37c4e55b4a2c5ea565c4ebf/04ac3197-7d0f-4301-bbaf-68daaee2b1a8/1666433101760.jpg", "instance": 194338021, "xform": 740320, "id": 82978907 }, { "download_small_url": "https://kf.kobotoolbox.org/api/v2/assets/ajDWYWQoe9Gw6WAnK8H4fG/data/194338021/attachments/82978905/", "mimetype": "image/jpeg", "filename": "deploymentsmaster/attachments/a46854ceb37c4e55b4a2c5ea565c4ebf/04ac3197-7d0f-4301-bbaf-68daaee2b1a8/1666434194815.jpg", "instance": 194338021, "xform": 740320, "id": 82978905 }, { "download_small_url": "https://kf.kobotoolbox.org/api/v2/assets/ajDWYWQoe9Gw6WAnK8H4fG/data/194338021/attachments/82978904/", "mimetype": "image/jpeg", "filename": "deploymentsmaster/attachments/a46854ceb37c4e55b4a2c5ea565c4ebf/04ac3197-7d0f-4301-bbaf-68daaee2b1a8/1666432849037.jpg", "instance": 194338021, "xform": 740320, "id": 82978904 }, { "download_small_url": "https://kf.kobotoolbox.org/api/v2/assets/ajDWYWQoe9Gw6WAnK8H4fG/data/194338021/attachments/82978903/", "mimetype": "image/jpeg", "filename": "deploymentsmaster/attachments/a46854ceb37c4e55b4a2c5ea565c4ebf/04ac3197-7d0f-4301-bbaf-68daaee2b1a8/1666432801510.jpg", "instance": 194338021, "xform": 740320, "id": 82978903 }, { "download_small_url": "https://kf.kobotoolbox.org/api/v2/assets/ajDWYWQoe9Gw6WAnK8H4fG/data/194338021/attachments/82978902/", "mimetype": "image/jpeg", "filename": "deploymentsmaster/attachments/a46854ceb37c4e55b4a2c5ea565c4ebf/04ac3197-7d0f-4301-bbaf-68daaee2b1a8/1666432764144.jpg", "instance": 194338021, "xform": 740320, "id": 82978902 }, { "download_small_url": "https://kf.kobotoolbox.org/api/v2/assets/ajDWYWQoe9Gw6WAnK8H4fG/data/194338021/attachments/82978901/", "mimetype": "image/jpeg", "filename": "deploymentsmaster/attachments/a46854ceb37c4e55b4a2c5ea565c4ebf/04ac3197-7d0f-4301-bbaf-68daaee2b1a8/1666432044571.jpg", "instance": 194338021, "xform": 740320, "id": 82978901 }, { "download_small_url": "https://kf.kobotoolbox.org/api/v2/assets/ajDWYWQoe9Gw6WAnK8H4fG/data/194338021/attachments/82978900/", "mimetype": "image/jpeg", "filename": "deploymentsmaster/attachments/a46854ceb37c4e55b4a2c5ea565c4ebf/04ac3197-7d0f-4301-bbaf-68daaee2b1a8/1666432742444.jpg", "instance": 194338021, "xform": 740320, "id": 82978900 } ]
我尝试了以下代码,但未能实现正确排序:
attachments.sort.forEach(zz => { return zz["filename"].match(/\b[0-9]{13}(?=\.[^.]+$)/) })
解决方案
错误原因
你使用了attachments.sort.forEach,这是错误的用法:sort是数组的排序方法,需要传入比较函数来定义排序规则,而不是用forEach遍历数组。
基础实现版本
// 从filename中提取13位数字后缀 function extractSuffix(filename) { const matchResult = filename.match(/\b[0-9]{13}(?=\.[^.]+$)/); return matchResult ? matchResult[0] : ''; } // 执行排序 attachments.sort((itemA, itemB) => { const suffixA = extractSuffix(itemA.filename); const suffixB = extractSuffix(itemB.filename); // 比较两个后缀在排序数组中的索引位置 return sort_based_on_this_order.indexOf(suffixA) - sort_based_on_this_order.indexOf(suffixB); });
这段代码的逻辑:
- 通过正则从每个附件的
filename中提取对应的13位数字后缀 - 使用
indexOf获取后缀在sort_based_on_this_order中的位置 - 根据索引差值排序:差值为负则
itemA排在itemB前,正则相反,完全匹配指定的排序顺序
性能优化版本
如果数组元素较多,indexOf每次遍历数组会影响性能,建议提前创建后缀到索引的映射:
// 创建后缀-索引映射表,将O(n)查找转为O(1) const suffixIndexMap = sort_based_on_this_order.reduce((map, suffix, index) => { map[suffix] = index; return map; }, {}); // 提取后缀的函数不变 function extractSuffix(filename) { const matchResult = filename.match(/\b[0-9]{13}(?=\.[^.]+$)/); return matchResult ? matchResult[0] : ''; } // 执行排序 attachments.sort((itemA, itemB) => { const suffixA = extractSuffix(itemA.filename); const suffixB = extractSuffix(itemB.filename); // 无匹配项默认放到数组末尾 const indexA = suffixIndexMap[suffixA] ?? sort_based_on_this_order.length; const indexB = suffixIndexMap[suffixB] ?? sort_based_on_this_order.length; return indexA - indexB; });
这个版本额外处理了无匹配后缀的情况,将这类附件自动放到排序后的数组末尾,同时大幅提升了排序效率。
内容的提问来源于stack exchange,提问作者Code Guy
相关产品推荐
相关产品推荐

