You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell如何实现接收两个Int列表返回对应元素索引的Int列表

实现参考

已知条件

  • 参考下标映射的源列表:list1 = [14,24,1,2,11,7,23,8,12,22,20,0,15,19,4,9,10,21,18,17,3,13,16,5,6,25]
  • 待查询的目标列表:list2 = [14,14,24,24,1,1,2,2]
  • 预期返回结果:[0,0,1,1,2,2,3,3]
  • 已有的工具函数能力:
elemIndex' :: Eq a => a -> [a] -> Int
elemIndex' x = fromMaybe (-1) . elemIndex x

该函数可以返回单个元素在参考列表中首次出现的下标,比如查询14在list1中的位置时返回0,查询不到元素时返回-1。

  • 待实现函数要求:
    类型签名固定为findIndex :: [Int] -> [Int] -> [Int],入参顺序为「参考键值列表」→「待查询元素列表」,返回值是待查询列表每个元素对应在参考列表下标的集合,支持递归实现或借助map等标准函数实现。

方案1:借助map实现(代码最简洁)

需求本质是遍历待查询列表的每一个元素,逐个调用已有的elemIndex'查询其在参考列表的下标,直接用map把查询逻辑映射到待查询列表的所有元素上即可,代码量极少:

findIndex :: [Int] -> [Int] -> [Int]
findIndex refList queryList = map (\element -> elemIndex' element refList) queryList

把题目给出的list1、list2传入该函数,就能直接得到预期的[0,0,1,1,2,2,3,3]结果。如果习惯用点自由风格写代码,还可以简化成findIndex refList = map (flip elemIndex' refList),执行效果完全一致。

方案2:纯递归实现

如果不想用高阶函数,按列表递归的常规思路写就行:

  1. 基准边界:当待查询列表为空时,直接返回空列表作为结果
  2. 递归逻辑:把待查询列表拆成头部元素和剩余尾部,先计算头部元素的下标,再递归处理尾部列表,最后把当前下标和递归返回的尾部结果拼接起来
    具体代码如下:
findIndex :: [Int] -> [Int] -> [Int]
-- 边界条件:没有待查询元素时返回空
findIndex _ [] = []
-- 拆分待查询列表递归处理
findIndex refList (x:xs) = elemIndex' x refList : findIndex refList xs

这个版本和map版本的执行逻辑、输出结果完全一致,没有额外依赖其他函数,完全符合递归实现的要求。


补充说明:现有elemIndex'在元素不存在时返回-1的逻辑,只要待查询列表的所有元素都在参考列表中就不会影响结果;如果后续需要处理元素不存在的异常场景,可以按需调整工具函数的返回逻辑。当前实现取元素首次出现位置的逻辑,和题目给出的示例预期完全对齐。

内容的提问来源于stack exchange,提问作者FrankZZZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:39:16