首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我对传感器的理解和js代码正确吗?

我对传感器的理解和js代码正确吗?
EN

Stack Overflow用户
提问于 2019-06-08 13:50:35
回答 2查看 808关注 0票数 4

我读过关于换能器的网页文章

Js

  • 传感器: JavaScript @ Elliott中高效的数据处理管道
  • 理解JavaScript @ Roman介质中的传感器

从一半很难理解..。

  • 什么是传感器?
  • JavaScript的简易换能器
  • 如何使用转换器提高数据转换的效率

克洛尔

  • 传感器是由里奇·希基-白兰地来的。
  • Transducers-Clojure.org

我阅读了Clojure官方教程约2页,并了解基本的语法。参考内建函数参考,了解换能器示例代码.

我对以上两篇文章的理解大概是75%.

我的问题

我想知道以下理解/js代码是正确的还是不正确的。请帮助me.<( _ )> )

关于传感器

  1. compose()返回的值是换能器。
  2. 换能器是通过传递给transduce()函数作为参数来执行的,另外,传感器是通过直接将数组传递给transducer()来执行的。
  3. 在(2)的过程中,不产生中间值,并且执行像下面链接这样的有效过程。
代码语言:javascript
复制
- [Understanding Transducers in JavaScript @ Roman Liutikov -Medium](https://medium.com/@roman01la/understanding-transducers-in-javascript-3500d3bd9624#6a68)

我的代码

代码语言:javascript
复制
"use strict";

const map = fn => arr => arr.map(fn),
filter = fn => arr => arr.filter(fn),
addReducer = arr => arr.reduce((acc, num) => acc + num, 0),
add1 = n => n + 1,
even = n => n % 2 === 0,

compose = (...fns) => initVal => fns.reduce((acc, fn) => fn(acc), initVal),
transduce = (xform, reducer, arr ) => reducer( xform(arr) );



const arr = [1,2,3],
transducer = compose(  /* called transducer or xform */
   map( add1 ), // 2,3,4
   filter( even ), // 2,4
);

console.log( transducer(arr) ) // 2,4
console.log( transduce(transducer, addReducer, arr) ) // 6
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-08 18:36:12

传感器利用一个事实,即功能组合抽象出的特性,即可以返回一个函数,而不是一个“正常值”:

代码语言:javascript
复制
const comp = f => g => x => f(g(x));

const add = x => y => x + y;

const sqr = x => x * x;

const add9 = comp(add) (sqr) (3); // returns a lambda

console.log(
  add9(6)); // 15

现在换能器本身是相当无聊的:

代码语言:javascript
复制
reduce => acc => x => /* body is specific to the transducer at hand */

它只是一个闭包,它需要一个还原器(即一个组合了两个参数的二进制函数),然后可以直接输入您喜欢的还原函数。

让我们看看地图换能器:

代码语言:javascript
复制
const mapper = f => (reduce => acc => x =>
  reduce(acc) (f(x)));

多余的括号只是说明了换能器关闭。在本例中,它通过我们的转换函数f关闭。接下来,我们将应用它:

代码语言:javascript
复制
// map transducer

const mapper = f => reduce => acc => x =>
  reduce(acc) (f(x));

// my favorite fold (reducing function)

const arrFold = alg => zero => xs => {
  let acc = zero;

  for (let i = 0; i < xs.length; i++)
    acc = alg(acc) (xs[i], i);

  return acc;
};

// reducer

const add = x => y => x + y;

// transformer

const sqr = x => x * x;

// MAIN

const main = arrFold(mapper(sqr) (add)) (0);

console.log(
  main([1,2,3])); // 14

没那么令人印象深刻对吧?换能器的真正威力来自于它们与功能组合的结合:

代码语言:javascript
复制
// map transducer

const mapper = f => reduce => acc => x =>
  reduce(acc) (f(x));

// filter transducer

const filterer = p => reduce => acc => x =>
  p(x) ? reduce(acc) (x) : acc;
  
// my favorite fold (reducing function)

const arrFold = alg => zero => xs => {
  let acc = zero;

  for (let i = 0; i < xs.length; i++)
    acc = alg(acc) (xs[i], i);

  return acc;
};

// helpers

const add = x => y => x + y; // reducer
const sqr = x => x * x; // transformer
const isOdd = x => (x & 1) === 1; // predicate
const comp = f => g => x => f(g(x));

// MAIN

const main = arrFold(comp(filterer(isOdd)) (mapper(sqr)) (add)) (0);

console.log(
  main([1,2,3])); // 10

虽然我们有两个传感器涉及,只有一个遍历通过Array。这个属性称为循环融合。由于换能器组合物返回另一个函数,评价顺序颠倒,即从左到右,而函数组合通常从右到左。

可重用性是另一个优势。你必须只定义一次换能器,并且可以在所有可折叠的数据类型中一次性使用它们。

同样值得注意的是,transduce只是一个方便的函数,理解这个概念并不重要。

关于换能器,差不多就是这样了。

票数 3
EN

Stack Overflow用户

发布于 2019-06-08 21:15:38

你的代码与换能器无关。您对filterm̀ap的定义表明它使用了普通的JS filtermap

代码语言:javascript
复制
const map = fn => arr => arr.map (fn),
const filter = fn => arr => arr.filter (fn),

const combo = compose(map(add1), filter(even));
combo(arr); ==> [2, 4]

所发生的情况是,使用map将初始数组传递给add1,后者将生成数组[2, 3, 4],然后将其传递给带有evenfilter,并创建一个新的数组[2, 4]

换能器也是如此:

代码语言:javascript
复制
const arr = [1, 2, 3];

const add1 = n => n + 1;
const even = n => n% 2 === 0;

const compose = (...fns) => {
  const [firstFunc, ...restFuncs] = fns.reverse();
  return (...args) => restFuncs.reduce((acc, fn) => fn(acc), firstFunc(...args));
};

const mapping = 
  fn => join => (acc, e) => join(acc, fn(e));

const filtering = 
  isIncluded => join => (acc, e) => isIncluded(e) ? join(acc, e) : acc;

const transducer = compose(mapping(add1), filtering(even));
const arrayJoin = (acc, e) => ([...acc, e]);
const result = arr.reduce(transducer(arrayJoin), []);
console.log(result);

所以区别在于,当你把join传给换能器时,就会发生这样的情况:

代码语言:javascript
复制
mapping(add1)(filtering(even)(arrayAdd))

filtering是添加到某些集合中的唯一步骤。当mapping调用join时,直接调用filtering。这就是为什么签名(acc, e)在工作部分和join函数上是相同的。当代码运行时,添加和过滤同时进行,结果只有一个生成的数组,而没有中间值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56507025

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档