RoundRobin功能方法 - 为什么我的功能有副作用? [英] RoundRobin functional approach - why does my function have side effects?

查看:120
本文介绍了RoundRobin功能方法 - 为什么我的功能有副作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标



我正在尝试创建一个循环算法( https://en.wikipedia.org/wiki/Round-robin_scheduling )。

这个函数应该得到如下的数组:

  [
[1,2],
[3,4]
]

并产生以下输出:

[1,3,2,4]



代码



为了达到这个目的,我决定像下面这样递归地实现循环:

  const roundRobin =(arr,results)=> {
if(arr.length === 0)返回结果; $(b)b
const newResults = arr.reduce((acc,current)=> {

if(current.length> 0){
acc.results。 push(current.shift());
acc.arr.push(current);
}
return acc;

},{arr:[],结果});

返回roundRobin(newResults.arr,newResults.results);
};

在这里,我感到了一系列结果,当我没有什么需要添加它。可以使用下面的代码:

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

const result = roundRobin(array,[]);



问题



在我的代码中,我是在我的 arr 参数中使用 reduce 来确保我不修改原始文件。但是,如果我在使用roundRobin之前和之后打印数组,则该变量已更改!以某种方式改变它!

问题:


  1. 如果我使用纯粹的reduce,我是否突变了我的参数?

  2. 是否有另一种纯粹的/实用的roundRobin方法?


解决方案



  1. 如果我使用reduce,这是纯粹的,我该如何改变我的参数?


功能参数不能真正发生变异;一个奇怪的想法 - 但我相信你的意思是提供给你函数的参数正在发生变化。是的,就像其他人指出的那样 .shift $ b

值得一提的是, .reduce 不是纯粹的,除非用户提供的lambda是纯的



  1. 是否有另一种实现roundRobin的纯粹/功能方式?


是的



  const isEmpty = xs => xs.length === 0 const head =([x,... xs])=> x const tail =([x,... xs])=> xsconst append =(xs,x)=> xs.concat([x])const roundRobin =([x,... xs],acc = [])=> x === undefined? acc:isEmpty(x)? roundRobin(xs,acc):roundRobin(append(xs,tail(x)),append(acc,head(x))const data = [[1,4,7,9],[2,5],[ 3,6,8,10,11,12]] console.log(roundRobin(data))// => [1,2,3,4,5,6,7,8,9,10,11,12] console.log(roundRobin([[1,2,3]]))// => [1,2,3] console.log(roundRobin([]))// => []  


Objective

I am trying to create a Round Robin algorithm ( https://en.wikipedia.org/wiki/Round-robin_scheduling ) in a pure functional way.

This function, is supposed to received an array like the following:

[
    [ 1, 2 ],
    [ 3, 4 ]
]

And produce the following output:

[ 1, 3, 2, 4 ]

Code

To achieve this, I decided to implement round robin recursively like the following:

const roundRobin = (arr, results) => {
    if (arr.length === 0) return results;

    const newResults = arr.reduce((acc, current) => {

        if (current.length > 0) {
            acc.results.push(current.shift());
            acc.arr.push(current);
        }
        return acc;

    }, { arr: [], results });

    return roundRobin(newResults.arr, newResults.results);
};

Here, I feel up an array of results, and I finish when I have nothing left to add to it. One would use this code like the following:

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

const result = roundRobin( array, [] );

Problem

In my code I am using reduce in my arr parameter to ensure I don't modify the original. However, if I print array before using roundRobin and after, the variable is changed ! I mutate it somehow!

Questions:

  1. If I am using reduce, which is pure, how am I mutating my parameters?
  2. Is there another pure/functional way of implementing roundRobin?

解决方案

  1. If I am using reduce, which is pure, how am I mutating my parameters?

Function parameters can't really be mutated; a strange thought – but I'm sure you meant the arguments supplied to your function are being mutated. And yeah, that's with .shift as others pointed out

And for what it's worth, .reduce isn't pure unless the user-supplied lambda is pure

  1. Is there another pure/functional way of implementing roundRobin?

Yep

const isEmpty = xs =>
  xs.length === 0
  
const head = ( [ x , ...xs ] ) =>
  x
  
const tail = ( [ x , ...xs ] ) =>
  xs

const append = ( xs , x ) =>
  xs.concat ( [ x ] )
  
const roundRobin = ( [ x , ...xs ] , acc = [] ) =>
  x === undefined
    ? acc
    : isEmpty ( x )
      ? roundRobin ( xs , acc )
      : roundRobin ( append ( xs , tail ( x ) )
                   , append ( acc , head ( x ) )
                   )

const data =
  [ [ 1 , 4 , 7 , 9 ]
  , [ 2 , 5 ]
  , [ 3 , 6 , 8 , 10 , 11 , 12 ]
  ]
                   
console.log ( roundRobin ( data ) )
// => [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ]

console.log ( roundRobin ( [ [ 1 , 2 , 3 ] ] ) )
// => [ 1 , 2 , 3 ]

console.log ( roundRobin ( [] ) )
// => []

这篇关于RoundRobin功能方法 - 为什么我的功能有副作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆