如何从动态镜头获取动态视图

时间:2017-05-15 03:26:37

标签: javascript functional-programming ramda.js

使用R.view dinamicly ...

const robotsNames = [ 'da Vinci Surgical System',  'KITT', 'The Tachikomas', 'Toyota violin-playing robot',
    'GERTY', 'Mega Man', 'Rock ‘Em Sock ‘Em Robots', 'Doraemon', 'Awesom-O', 'HK-47', 'ED-209', 'Beer-Fetching Robot',
    'Bishop', 'The Energizer Bunny', 'Clank', 'Daft Punk', 'Johnny 5', 'The Robot', 'Roboto', 'Marvin the Paranoid Android',
    'Lego Mindstorms NXT', 'Robbie', 'Astro Boy', 'The Iron Giant', 'Optimus Prime', 'Roomba', 'DJ Roomba', 'Cindi Mayweather',
    'Rosie', 'Crow T. Robot/Tom Servo', 'K-9', 'The Terminator', 'The Maschinenmensch, aka Maria', 'ASIMO', 'GLaDOS', 'HAL 9000',
    'The Final Five', 'Sojourner', 'Data', 'R2D2', 'Bender Bending Rodriguez', 'Wall-E' ];

const getRandomInt =  R.curry((min, max) => {
    return Math.floor(Math.random() * (max - min + 1)) + min;
})
const getRandomFromZero = getRandomInt(0);
const lensRandomRobot = R.pipe(R.length, getRandomFromZero, R.lensIndex);

// NOT WORK...
const randomRobot = R.pipe(lensRandomRobot, R.view);
const robot = randomRobot(robotsNames);

// THIS WORKS ..
// const robot = R.view(lensRandomRobot(robotsNames))(robotsNames) // I dont want to pass the values twiice

console.log(robot);
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.23.0/ramda.min.js"></script>

2 个答案:

答案 0 :(得分:1)

如果您想避免重复R.converge

,请在R.pipe中使用randomRobot代替robotsNames

const robotsNames = [ 'da Vinci Surgical System',  'KITT', 'The Tachikomas', 'Toyota violin-playing robot',
    'GERTY', 'Mega Man', 'Rock ‘Em Sock ‘Em Robots', 'Doraemon', 'Awesom-O', 'HK-47', 'ED-209', 'Beer-Fetching Robot',
    'Bishop', 'The Energizer Bunny', 'Clank', 'Daft Punk', 'Johnny 5', 'The Robot', 'Roboto', 'Marvin the Paranoid Android',
    'Lego Mindstorms NXT', 'Robbie', 'Astro Boy', 'The Iron Giant', 'Optimus Prime', 'Roomba', 'DJ Roomba', 'Cindi Mayweather',
    'Rosie', 'Crow T. Robot/Tom Servo', 'K-9', 'The Terminator', 'The Maschinenmensch, aka Maria', 'ASIMO', 'GLaDOS', 'HAL 9000',
    'The Final Five', 'Sojourner', 'Data', 'R2D2', 'Bender Bending Rodriguez', 'Wall-E' ];

const getRandomInt =  R.curry((min, max) => {
    return Math.floor(Math.random() * (max - min + 1)) + min;
})
const getRandomFromZero = getRandomInt(0);
const lensRandomRobot = R.pipe(R.length, getRandomFromZero, R.lensIndex);

// CHANGE MADE HERE
const randomRobot = R.converge(R.view, [lensRandomRobot, R.identity]);
const robot = randomRobot(robotsNames);


console.log(robot);
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.23.0/ramda.min.js"></script>

答案 1 :(得分:1)

两件事:

  • Damon的答案很好。 converge按预期完成工作。但是有几种选择需要考虑。 converge非常特定于Ramda。 FP世界更熟悉的东西可能会引起你的兴趣。 lift更为常见。您可以像这样使用它:

    const randomRobot = R.lift(R.view)(lensRandomRobot, R.identity);
    

    或者,最好的是ap,除了view中的参数顺序与ap提供的参数顺序相反外,这将是完美的,因此需要flip }以及 *

    const randomRobot = R.ap(R.flip(R.view), lensRandomRobot);
    

    您可以在 Ramda REPL 上看到这些方法。

  • 其次,在功能代码中引入随机源是一个奇怪的想法。显然,使用随机值的任何内容都不再是引用透明的。这就是Ramda不提供随机/随机播放功能的原因。

    Ramda在某一点尝试了随机性,尝试使用引用透明版本。但最终它被放弃作为一个糟糕的匹配,但that code可能会帮助您创建基于随机代码的可测试版本。

* 关键是当ap应用于函数时,它的行为如下:

ap(f, g)(x); //=> f(x)(g(x))

对于像Ramda一样的函数,这相当于

ap(f, g)(x); //=> f(x, g(x))