使用purrr::walk()向FLIFO栈添加对象失败,循环实现正常
解决
purrr::walk()无法往FLIFO栈推入元素的问题 我猜你大概率是在使用walk()时搞反了push()函数的参数传递顺序,才导致这个问题的。咱们一步步理清楚:
为什么for循环能正常工作?
你的for循环写法是完全正确的:
for( card in cards ) { flifo::push(deck_loop, card) }
这里你明确把栈对象deck_loop作为push()的第一个参数(要求的栈对象),把每个card作为第二个参数(要推入的元素),完全符合flifo::push(stack, elem)的参数定义,所以每次迭代都能正确往栈里添加元素。
为什么purrr::walk()的写法失效?
如果你的walk()代码是类似下面这种:
purrr::walk(cards, flifo::push, deck_purrr)
那问题就出在参数顺序上!purrr的迭代函数(包括walk())会默认把迭代的每个元素(也就是cards里的每个字母)作为第一个参数传给目标函数(flifo::push),后面跟着你额外传递的参数(deck_purrr)。这就相当于每次调用push(card, deck_purrr),完全颠倒了push()要求的(stack, elem)顺序,自然不会往deck_purrr里推入任何元素。
正确的三种写法
1. 使用匿名函数明确指定参数
最直观的方式就是用匿名函数把参数顺序固定好:
purrr::walk(cards, function(card) { flifo::push(deck_purrr, card) })
2. 使用purrr的公式语法
如果你喜欢简洁的写法,用公式语法也能达到同样效果,.x代表迭代的每个元素:
purrr::walk(cards, ~flifo::push(deck_purrr, .x))
3. 使用purrr::partial()固定栈参数
这种方式适合需要重复往同一个栈推入元素的场景,提前把栈参数固定好:
# 先创建一个绑定了deck_purrr的push函数 push_to_deck <- purrr::partial(flifo::push, stack = deck_purrr) # 再用walk迭代调用 purrr::walk(cards, push_to_deck)
验证结果
运行完上面任意一种写法后,再执行:
message("Deck size (purrr version): ", as.integer(flifo::size(deck_purrr) / 96), " cards")
就能得到和for循环一样的结果:"Deck size (purrr version): 5 cards"
内容的提问来源于stack exchange,提问作者wibeasley
相关产品推荐
相关产品推荐

