gpt4 book ai didi

javascript - 使用 converge 生成列表的所有旋转时出现意外结果

转载 作者:搜寻专家 更新时间:2023-11-01 05:19:07 25 4
gpt4 key购买 nike

我正在尝试获取列表 v 的所有旋转。因此,在 rotations 的定义中,我使用翻转版本的 rotateLeft 作为第一个分支函数(为了首先接受列表),然后是返回list [0, 1, 2, ..., v.length-1],以map为收敛函数。

const {curry,mathMod,pipe,splitAt,reverse,unnest,converge,map,flip,length,times,identity} = require("ramda");

const v = [1,2,3,4];

const rotateLeft = curry((n,vet) => {
const i = mathMod(n,vet.length);
return pipe(
splitAt(i),
reverse,
unnest
)(vet);
});

const rotations = converge(map,[
flip(rotateLeft),
pipe(length,times(identity))
]);

rotations(v);

但是,这并没有返回我预期的结果。相反,如果我按如下方式重写它,它会工作正常:

map(flip(rotateLeft)(v),
pipe(length,times(identity))(v));

// gives [[1,2,3,4],[2,3,4,1],[3,4,1,2],[4,1,2,3]]

据我所知,converge 将两个分支函数应用于 v,然后将结果作为参数提供给 map。是对的吗?那么为什么 rotations(v) 不返回同样的东西呢?

Code

使用reduce的更简洁的版本

受您在 vanilla JS 中的版本的启发,我提出了以下 reduceRotations 函数,它不使用 map< 的索引参数 或以明显的方式递归。然后,当然,我以完全无意义的方式将其翻译成 vanilla Ramda。 :)

const {converge,reduce,always,append,pipe,last,head,tail,identity,unapply} = require("ramda");

const reduceRotations = (v) => {
const rotate = (v) => append(head(v),tail(v));
return reduce(
(acc,_) => append(rotate(last(acc)),acc),
[v],
tail(v)
);
};

const pointFreeRotations =
converge(reduce,[
always(converge(append,[
pipe(last,converge(append,[head,tail])),
identity
])),
unapply(identity),
tail
]);

Code

又一个

以下等效函数使用 scan 而不是 reduce

const {converge,scan,always,append,head,tail,identity} = require("ramda");

const scanRotations = (v) => {
const rotate = (v) => append(head(v),tail(v));
return scan(rotate,v,tail(v));
};

const scanPointFreeRotations =
converge(scan,[
always(converge(append,[head,tail])),
identity,
tail
]);

Code

最佳答案

这是因为 converge 将提供给它的最长函数的元数作为其元数。

因此,由于 flip(rotateLeft).length//=> 2pipe(length,times(identity))//=> 1,旋转将有长度 2。但是你显然想要一个一元函数。最简单的修复方法是简单地将 flip(rotateLeft) 包裹在 unary 中:

const rotateLeft = curry((n,vet) => {
const i = mathMod(n,vet.length);
return pipe(
splitAt(i),
reverse,
unnest
)(vet);
});

const rotations = converge (map, [
unary ( flip (rotateLeft) ),
pipe ( length, times(identity) )
])

const v = [1,2,3,4];

console .log (
rotations (v)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script><script>
const {curry, mathMod, pipe, splitAt, reverse, unnest, converge, map, unary, flip, length, times, identity} = R </script>

另请注意,这并不真的需要 Ramda 的所有机器。在 vanilla JS 中很容易做到这一点:

const rotations = v => v .map ( (_, i) => v .slice (i) .concat ( v .slice(0, i) ) )

关于javascript - 使用 converge 生成列表的所有旋转时出现意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56266508/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com