【问题标题】:Javascript declarative/immutable version of 'maybe push'?'也许推'的Javascript声明/不可变版本?
【发布时间】:2021-12-16 09:42:08
【问题描述】:

我有这样的代码:

A = [1,2,3]
if (condition) {A.push(4)}
A.push(5)

但我的数组实际上是不可变的,所以我不能这样做。我怎样才能在一个表达式中完成所有操作?我不希望中间有一个空值。

【问题讨论】:

    标签: javascript functional-programming immutability


    【解决方案1】:

    这是一种方法:

    A = [1, 2, 3, ...(condition ? [4] : []), 5]
    

    如果这在您的代码库中很常见,并且您希望保持未定义,那么您可以编写一个带有哨兵的过滤器函数。

    const REMOVE = symbol('removeme')
    const A = clean([1, 2, 3, condition ? 4 : REMOVE, 5])
    function clean(arr) {return arr.filter(x=>x!==REMOVE)}
    

    【讨论】:

      【解决方案2】:

      你可以在这里使用Writer monad。

      // type Writer t a = { value :: a, array :: [t] }
      
      // pure :: a -> Writer t a
      const pure = (value) => ({ value, array: [] });
      
      // bind :: (Writer t a, a -> Writer t b) -> Writer t b
      const bind = (writerA, arrow) => {
          const writerB = arrow(writerA.value);
          const array = [...writerA.array, ...writerB.array];
          return { value: writerB.value, array };
      };
      
      // tell :: [t] -> Writer t ()
      const tell = (array) => ({ value: undefined, array });
      
      const writer = (gen) => {
          const next = (data) => {
              const { value, done } = gen.next(data);
              return done ? value : bind(value, next);
          };
      
          return next(undefined);
      };
      
      const example = (condition) => writer(function* () {
          yield tell([1, 2, 3]);
          if (condition) yield tell([4]);
          return tell([5]);
      }());
      
      console.log(example(true).array); // [1,2,3,4,5]
      console.log(example(false).array); // [1,2,3,5]

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-05
      • 1970-01-01
      • 2012-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多