如何按索引在LoL结构中移动元素并重构操作后的LoL?
嘿,这个列表间元素移动后重构LoL的问题我太熟了!我来给你一步步拆解思路,帮你搞定NewState的生成~
核心思路拆解
其实重构LoL的本质就是三个步骤:
- 把From位置的子列表里的目标元素拿掉,得到一个“被掏空”的新子列表
- 把这个目标元素加到To位置的子列表里,得到一个“被填充”的新子列表
- 把原LoL里的From和To位置的子列表,分别替换成上面两个新子列表,其余子列表保持原样,就得到了
NewState
这个思路完全不依赖子列表的固定数量,不管未来你要支持3个还是10个,逻辑都通用。
举个直观的例子
假设你的初始State是:
[[1, 2, 3], [4, 5], [6]]
要把From=1(第一个子列表,这里用1-based索引)里的元素2移动到To=3(第三个子列表),那:
- 从第一个子列表拿掉
2,得到[1, 3] - 把
2加到第三个子列表,得到[6, 2] - 替换原LoL的对应位置,最终
NewState就是:
[[1, 3], [4, 5], [6, 2]]
具体代码实现(以Erlang为例,适配你的move_elem/4)
我给你写个可复用的版本,包含辅助函数来处理列表操作:
move_elem(From, To, TargetElem, State) -> % 先处理From位置:移除目标元素,得到新的子列表 {UpdatedFromList, _} = remove_first_matching(lists:nth(From, State), TargetElem), % 处理To位置:添加目标元素到子列表(这里加到开头,想加末尾就换成 ++ [TargetElem]) UpdatedToList = [TargetElem | lists:nth(To, State)], % 先替换From位置,再替换To位置,得到最终NewState TempState = replace_nth(From, UpdatedFromList, State), NewState = replace_nth(To, UpdatedToList, TempState), NewState. % 辅助函数:从列表中移除第一个匹配的元素 remove_first_matching(List, Elem) -> remove_first_matching(List, Elem, []). remove_first_matching([Elem | Rest], Elem, Acc) -> {lists:reverse(Acc) ++ Rest, Elem}; remove_first_matching([H | Rest], Elem, Acc) -> remove_first_matching(Rest, Elem, [H | Acc]); remove_first_matching([], _, Acc) -> {lists:reverse(Acc), undefined}. % 辅助函数:替换列表中第N个元素(1-based索引,要0-based就改起始值) replace_nth(1, NewVal, [_ | Rest]) -> [NewVal | Rest]; replace_nth(N, NewVal, [H | Rest]) when N > 1 -> [H | replace_nth(N-1, NewVal, Rest)]; replace_nth(_, _, []) -> [].
关键细节提醒
- 索引问题:上面用的是1-based索引(也就是第一个子列表位置是1),如果你习惯用0-based,只要把
lists:nth/2的参数减1,replace_nth/3的起始判断改成0就行 - 边界处理:可以加个判断,如果
From或To超出子列表数量,直接返回原State或者抛出提示,避免报错 - 元素移除逻辑:这里是移除第一个匹配的元素,如果你要移除指定位置的元素(比如From子列表的第K个元素),只要把
remove_first_matching改成按位置移除的逻辑就行
这样不管你未来子列表数量怎么配置,这个逻辑都能直接复用~
内容的提问来源于stack exchange,提问作者sten
相关产品推荐
相关产品推荐

