函数 功能 30-seconds-of-code

函数 功能

原文:https://github.com/Chalarangelo/30-seconds-of-code

作者:Chalarangelo

翻译:http://caibaojian.com/30-seconds-of-code.html

译者:蔡宝坚

收集有用的 Javascript 片段, 你可以在30秒或更少的时间里理解。

chainAsync:链异步函数

循环遍历包含异步事件的函数数组,当每个异步事件完成调用next

const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); };
/*
chainAsync([
  next => { console.log('0 seconds'); setTimeout(next, 1000); },
  next => { console.log('1 second');  setTimeout(next, 1000); },
  next => { console.log('2 seconds'); }
])
*/
compose:执行从右向左的函数组合。

使用Array.reduce()执行从右向左的函数组合。最后一个 (最右边) 的函数可以接受一个或多个参数;其余的函数必须是一元的。

const compose = (...fns) => fns.reduce((f,g)=> (...args) => f(g(...args)))
/*
const add5 = x => x + 5
const multiply = (x, y) => x * y
const multiplyAndAdd5 = compose(add5, multiply)
multiplyAndAdd5(5, 2) -> 15
*/
pipe:执行从左向右的函数组合

使用Array.reduce()与扩展运算符(...)执行从左向右的函数组合,第一个(最左边的)函数可以接受一个或多个参数;其余的函数必须是一元的

//(...fns)==>剩余运算符,它将成为一个由剩余参数组成的真数组[5,6]
const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
/*
const add5 = x => x + 5
const multiply = (x, y) => x * y
const multiplyAndAdd5 = pipeFunctions(multiply, add5)
multiplyAndAdd5(5, 2) -> 15
*/
curry:Curries a function. /*********************************/

使用递归。如果提供的参数 (变量) 的数量足够, 请调用传递的函数args f。否则, 返回需要其余参数的扩充函数f。如果你想咖喱一个函数, 接受可变数目的参数 (如Math.min()), 可以选择将参数的个数传递到第二个参数arity(可变函数).

const curry = (fn, arity = fn.length, ...args) =>
arity <= args.length
? fn(...args)
: curry.bind(null, fn, arity, ...args);
// curry(Math.pow)(2)(10) -> 1024
// curry(Math.min, 3)(10)(50)(2) -> 2
functionName:记录函数的名称

使用console.debug()和传递的方法的name属性将方法的名称记录到控制台的debug通道中。

const functionName = fn => (console.debug(fn.name), fn);
// functionName(Math.max) -> max (logged in debug channel of console)
runPromisesInSeries:运行一系列的承诺系列。

使用Array.reduce()创建一个承诺链, 每个承诺在解决时返回下一个承诺。

const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());
// const delay = (d) => new Promise(r => setTimeout(r, d))
// runPromisesInSeries([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete
sleep:延迟异步函数的执行

延迟执行async的函数的一部分,将其放入休眠状态,返回Promise

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
/*
async function sleepyWork() {
  console.log('I\'m going to sleep for 1 second.');
  await sleep(1000);
  console.log('I woke up after 1 second.');
}
*/
arrayAverage:返回数字数组的平均值。

使用Array.reduce()将每个值添加到累加器中, 并以0的值初始化, 除以数组的length

const arrayAverage = arr => arr.reduce((acc,curVal)=>acc + curVal) /arr.length
// arrayAverage([1,2,3]) -> 2
arraySum:返回一个数字数组的总和

使用 Array.reduce()将每个值添加到累加器中,并以0值初始化

const arraySum = arr => arr.reduce((acc,curVal)=>acc+curVal,0)
// arraySum([1,2,3,4]) -> 10
collatz:应用 Collatz 算法。

如果n是偶数, 则返回n/2。否则返回3n+1.

const collatz = n => (n % 2 == 0) ? (n / 2) : (3 * n + 1);
// collatz(8) --> 4
// collatz(5) --> 16
collatz:将数字转换为数字数组

将数字转换为字符串,在ES6([...string])中使用扩展运算符生成数组,使用Array.map()parseInt()将每个值转换为整数

const colltaz = n => [...'' +n ].map(i=>parseInt(i))
// digitize(2334) -> [2, 3, 3, 4]

digitize

返回两点之间的距离。

使用Math.hypot()计算两个点之间的欧氏距离。

const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0);
// distance(1,1, 2,3) -> 2.23606797749979
distance:计算数字的阶乘

使用递归。如果n小于或等于1, 则返回1。否则, 返回n的乘积和n - 1的阶乘。如果n为负数, 则引发异常。

const distance  = n => n < 0 ? (() => { throw new TypeError('Negative numbers are not allowed!') })(): n <= 1 ? 1 : n * factorial(n - 1);
// factorial(6) -> 720
fibolacci:生成一个数组,包含斐波那契数列,知道第n个项

创建一个指定长度的空数组, 初始化前两个值 (01)。使用Array.reduce()可将值添加到数组中, 方法是使用前两个值的总和, 但前两个数值除外。

const fibonacci = n =>
Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []);
// fibonacci(5) -> [0,1,1,2,3]

gcd

计算两个数字之间最大的公共除数。

使用递归。基本情况是当y等于0时。在这种情况下, 返回x。否则, 返回y的 GCD 和除法的其余部分x/y.

const gcd = (x, y) => !y ? x : gcd(y, x % y);
// gcd (8, 36) -> 4

isDivisible

检查第一个数值参数是否可被另一个数字变量整除。

使用模数运算符 (%) 检查余数是否等于0.

const isDivisible = (dividend, divisor) => dividend % divisor === 0;
// isDivisible(6,3) -> true

iseven

如果给定的数字为偶数, 则返回true, 否则为false

检查一个数字是奇数还是使用模数 (%) 运算符。如果数字为偶数, 则返回true, 如果数字为奇数, 则为false

const isEven = num => num % 2 === 0;
// isEven(3) -> false

median

返回数字数组的中间值。

找到数组的中间, 使用Array.sort()来对值进行排序。如果length为奇数, 则返回中点的数字, 否则为两个中间数的平均值。

const median = arr => {
const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b);
return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
};
// median([5,6,50,1,-5]) -> 5
// median([0,10,-2,7]) -> 3.5

palindrome

如果给定字符串为回文, 则返回true, 否则为false

转换字符串toLowerCase()并使用replace()从其中删除非字母数字字符。然后,split('')到各个字符,reverse(),join(''), 并将其与原始的、不可逆转的字符串进行比较, 然后将其转换为tolowerCase().

const palindrome = str => {
const s = str.toLowerCase().replace(/[\W_]/g,'');
return s === s.split('').reverse().join('');
}
// palindrome('taco cat') -> true

percentile

使用百分比公式计算给定数组中有多少个数小于或等于给定值。

使用Array.reduce()计算值的下面有多少, 有多少个数是相同的值, 并应用百分比公式。

const percentile = (arr, val) =>
100 * arr.reduce((acc,v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length;
// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55

powerset

返回给定数字数组的 powerset。

使用Array.reduce()Array.map()组合, 以循环访问元素并将其合并到包含所有组合的数组中。

const powerset = arr =>
arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]);
// powerset([1,2]) -> [[], [1], [2], [2,1]]

randomIntegerInRange

返回指定范围内的随机整数。

使用Math.random()生成一个随机数并将其映射到所需的范围, 使用Math.floor()使其成为整数。

const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
// randomIntegerInRange(0, 5) -> 2

randomNumberInRange

返回指定范围内的随机数。

使用Math.random()生成随机值, 并使用乘法将其映射到所需的范围。

const randomNumberInRange = (min, max) => Math.random() * (max - min) + min;
// randomNumberInRange(2,10) -> 6.0211363285087005
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!要将ATK-ESP8266连接到原子云,您可以按照以下步骤进行操作: 1. 首先,确保您已经在原子云上创建了一个账户,并且已经创建了一个设备。 2. 在ATK-ESP8266上,您需要使用Arduino IDE或类似的开发环境来编写和上传代码。确保您已经安装了适当的驱动程序和库。 3. 在代码中,您需要使用ESP8266WiFi库来连接到Wi-Fi网络。您可以使用以下代码片段作为起点: ```cpp #include <ESP8266WiFi.h> const char* ssid = "Your_WiFi_SSID"; const char* password = "Your_WiFi_Password"; void setup() { Serial.begin(9600); delay(10); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void loop() { // Your code here } ``` 请将 "Your_WiFi_SSID" 替换为您的Wi-Fi网络名称,将 "Your_WiFi_Password" 替换为您的Wi-Fi密码。 4. 编译并上传代码到ATK-ESP8266。确保ATK-ESP8266已经连接到计算机,并选择正确的端口和开发板类型。 5. 在原子云上,找到您创建的设备,并获取设备的设备ID和访问密钥。 6. 在代码中,您需要使用MQTT库来连接到原子云,并将数据发布到设备。您可以使用以下代码片段作为参考: ```cpp #include <PubSubClient.h> const char* mqtt_server = "mqtt.atomiot.com"; const int mqtt_port = 1883; const char* device_id = "Your_Device_ID"; const char* access_key = "Your_Access_Key"; WiFiClient espClient; PubSubClient client(espClient); void setup() { // ... client.setServer(mqtt_server, mqtt_port); client.setCallback(callback); while (!client.connected()) { if (client.connect(device_id, access_key, "")) { Serial.println("Connected to Atom IoT Cloud"); } else { Serial.print("Failed to connect to Atom IoT Cloud, rc="); Serial.print(client.state()); Serial.println(" retrying in 5 seconds"); delay(5000); } } // ... } void loop() { if (!client.connected()) { reconnect(); } client.loop(); // Your code here } void callback(char* topic, byte* payload, unsigned int length) { // Handle incoming messages } void reconnect() { while (!client.connected()) { if (client.connect(device_id, access_key, "")) { Serial.println("Connected to Atom IoT Cloud"); } else { Serial.print("Failed to connect to Atom IoT Cloud, rc="); Serial.print(client.state()); Serial.println(" retrying in 5 seconds"); delay(5000); } } } ``` 请将 "Your_Device_ID" 替换为您的设备ID,将 "Your_Access_Key" 替换为您的设备访问密钥。 7. 编译并上传代码到ATK-ESP8266。 完成上述步骤后,您的ATK-ESP8266应该能够连接到原子云,并可以通过MQTT协议与其通信。您可以根据需要在 `loop()` 函数中添加更多的代码来处理传感器数据或执行其他操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值