携程做旅游的网站,石家庄商城网站制作,做网站建设公司,关于网站建设的一些事目录
2629. 复合函数
2631. 分组
2634. 过滤数组中的元素
2635. 转换数组中的每个元素 2637. 有时间限制的 Promise 对象 2648. 生成斐波那契数列
2649. 嵌套数组生成器
2665. 计数器 II
2666. 只允许一次函数调用 2629. 复合函数
恒等函数 在数学里#xff0c;恒等函…
目录
2629. 复合函数
2631. 分组
2634. 过滤数组中的元素
2635. 转换数组中的每个元素 2637. 有时间限制的 Promise 对象 2648. 生成斐波那契数列
2649. 嵌套数组生成器
2665. 计数器 II
2666. 只允许一次函数调用 2629. 复合函数
恒等函数 在数学里恒等函数为一无任何作用的函数它总是传回和其引数相同的值。换句话说恒等函数为函数f(x) x输入等于输出。 复合函数 复合函数是数学中的概念它指的是将一个函数的输出作为另一个函数的输入从而创建一个新的函数。简单来说复合函数是通过将一个函数的结果传递给另一个函数来实现函数的组合。 复合函数的定义通常表示为 f(g(x))其中 g(x) 是一个函数f(x) 是另一个函数。这意味着先应用 g(x)然后将结果作为 f(x) 的输入。通过这种方式我们可以将多个简单函数组合成一个更复杂的函数。 请你编写一个函数它接收一个函数数组 [f1, f2, f3… fn] 并返回一个新的函数 fn 它是函数数组的 复合函数 。
[f(x) g(x) h(x)] 的 复合函数 为 fn(x) f(g(h(x))) 。
一个空函数列表的 复合函数 是 恒等函数 f(x) x 。
你可以假设数组中的每个函数接受一个整型参数作为输入并返回一个整型作为输出。
题解
var compose function (funcs) {if (funcs.length 0) {return function (x) {return x;};}return function (x) {let result x;for (let i funcs.length - 1; i 0; i--) {result funcs[i](result);}return result;};
}
这个函数接受一个函数数组 funcs 作为参数。
首先我们检查函数数组是否为空如果为空意味着没有需要复合的函数因此返回一个恒等函数 function(x) { return x; }。
然后我们返回一个新的函数这个函数接受参数 x表示输入的整型参数。
在函数内部我们使用一个循环从后往前遍历函数数组并将每个函数的结果作为下一个函数的输入最后返回整个复合函数的结果。
例如如果函数数组为 [f, g, h]那么复合函数为 fn(x) f(g(h(x)))。
使用这个复合函数可以按照数组中函数的顺序依次调用它们将每个函数的结果作为下一个函数的输入最终得到复合函数的结果。
2631. 分组
请你编写一段可应用于所有数组的代码使任何数组调用 array. groupBy(fn) 方法时它返回对该数组 分组后 的结果。
数组 分组 是一个对象其中的每个键都是 fn(arr[i]) 的输出的一个数组该数组中含有原数组中具有该键的所有项。
提供的回调函数 fn 将接受数组中的项并返回一个字符串类型的键。
每个值列表的顺序应该与元素在数组中出现的顺序相同。任何顺序的键都是可以接受的。
请在不使用 lodash 的 _.groupBy 函数的前提下解决这个问题。
示例 输入
array [{id:1},{id:1},{id:2}
],
fn function (item) { return item.id;
}
输出
{ 1: [{id: 1}, {id: 1}], 2: [{id: 2}]
}
解释
输出来自函数 array.groupBy(fn)。
分组选择方法是从数组中的每个项中获取 id 。
有两个 id 为 1 的对象。所以将这两个对象都放在第一个数组中。
有一个 id 为 2 的对象。所以该对象被放到第二个数组中。 题解
Array.prototype.groupBy function (fn) {return this.reduce((result, item) {const key fn(item);if (result[key]) {result[key].push(item);} else {result[key] [item];}return result;}, {});
};
这段代码定义了一个名为groupBy的方法该方法是通过修改Array的原型来实现的。通过调用groupBy方法我们可以将一个数组按照指定的函数进行分组。
代码的实现逻辑如下 groupBy方法接受一个函数fn作为参数。 在方法体内使用reduce函数对数组进行迭代。reduce函数的作用是对数组中的每个元素执行一个回调函数并将回调函数的返回值用作下一次迭代的初始值。 在每次迭代中调用fn函数并传入当前元素item作为参数将返回值保存在key变量中。该函数用于确定每个元素所属的组别。 判断result对象中是否已经存在以key为键的属性。如果已经存在则将当前元素item添加到对应的数组中。如果不存在则创建以key为键的属性并将当前元素item作为数组的第一个元素。 最后返回最终的结果对象result。
总之这段代码的作用是将一个数组按照指定的函数对元素进行分组返回一个以分组结果为值的对象。
2634. 过滤数组中的元素
给定一个整数数组 arr 和一个过滤函数 fn并返回一个过滤后的数组 filteredArr 。
fn 函数接受一个或两个参数
arr[i] - arr 中的数字i - arr[i] 的索引
filteredArr 应该只包含使表达式 fn(arr[i], i) 的值为 真值 的 arr 中的元素。真值 是指 Boolean(value) 返回参数为 true 的值。
请在不使用内置的 Array.filter 方法的情况下解决该问题。 输入arr [0,10,20,30], fn function greaterThan10(n) { return n 10; }
输出 [20,30]
解释
const newArray filter(arr, fn); // [20, 30]
过滤函数过滤掉不大于 10 的值 题解
var filter function (arr, fn) {let filteredArr [];for (let i 0; i arr.length; i) {if (fn(arr[i], i)) {filteredArr.push(arr[i]);}}return filteredArr;
}这段代码定义了一个名为filter的函数它接受两个参数arr和fn。
函数的作用是对数组arr中的每个元素调用fn函数进行过滤将满足条件的元素放入新的数组filteredArr中并将filteredArr作为函数的返回值。
具体的实现逻辑如下
创建一个空数组filteredArr用于存储过滤后的元素。使用for循环遍历数组arr的每个元素。对于每个元素通过调用fn函数并传入该元素和当前索引i作为参数进行判断。如果fn函数的返回值为true则将该元素添加到filteredArr数组中。循环结束后返回filteredArr数组作为函数的结果。
总结这段代码实现了一个自定义的filter函数可以通过传入不同的条件函数对数组中的元素进行过滤并将满足条件的元素放入一个新数组中返回。
2635. 转换数组中的每个元素
编写一个函数这个函数接收一个整数数组 arr 和一个映射函数 fn 通过该映射函数返回一个新的数组。
返回数组的创建语句应为 returnedArray[i] fn(arr[i], i) 。
请你在不使用内置方法 Array.map 的前提下解决这个问题。
示例 输入arr [1,2,3], fn function plusone(n) { return n 1; }
输出[2,3,4]
解释
const newArray map(arr, plusone); // [2,3,4]
此映射函数返回值是将数组中每个元素的值加 1。 题解 var map function(arr, fn) {var returnedArray [];for (var i 0; i arr.length; i) {returnedArray[i] fn(arr[i], i);}return returnedArray;
};
这段代码定义了一个名为 map 的函数它接受两个参数一个数组和一个函数。函数的作用是对数组中的每个元素进行处理并返回处理后的结果。
在函数中首先创建了一个名为 returnedArray 的空数组。接下来使用循环遍历数组中的每个元素并调用传入的函数对其进行处理。处理后的结果被存储在 returnedArray 数组的相应索引位置上。
最后函数返回了处理后的数组 returnedArray。 2637. 有时间限制的 Promise 对象
请你编写一个函数它接受一个异步函数 fn 和一个以毫秒为单位的时间 t。它应根据限时函数返回一个有 限时 效果的函数。函数 fn 接受提供给 限时 函数的参数。
限时 函数应遵循以下规则
如果 fn 在 t 毫秒的时间限制内完成限时 函数应返回结果。如果 fn 的执行超过时间限制限时 函数应拒绝并返回字符串 Time Limit Exceeded 。
示例 输入
fn async (n) { await new Promise(res setTimeout(res, 100)); return n * n;
}
inputs [5]
t 50
输出{rejected:Time Limit Exceeded,time:50}
解释
const limited timeLimit(fn, t)
const start performance.now()
let result;
try {const res await limited(...inputs)result {resolved: res, time: Math.floor(performance.now() - start)};
} catch (err) {result {rejected: err, time: Math.floor(performance.now() - start)};
}
console.log(result) // 输出结果提供的函数设置在 100ms 后执行完成但是设置的超时时间为 50ms所以在 t50ms 时拒绝因为达到了超时时间。 题解 var timeLimit function (fn, t) {return async function (...args) {return new Promise((resolve, reject) {let timedOut false;// 执行异步函数并传递参数const result fn(...args);// 设置超时时间超过指定时间后Promise对象会被拒绝并返回字符串Time Limit ExceededsetTimeout(() {timedOut true;reject(Time Limit Exceeded);}, t);// 监听异步函数的完成result.then((value) {if (!timedOut) {resolve(value);}}).catch((error) {if (!timedOut) {reject(error);}});});};
} 这段代码定义了一个名为timeLimit的函数该函数接受两个参数fn和t。fn是一个异步函数t是一个表示超时时间的数字。该函数返回一个新的异步函数。
新的异步函数接受任意数量的参数它的功能是在指定的时间内执行传入的异步函数fn并返回一个Promise对象。
在新的异步函数内部首先声明了一个变量timedOut其初始值为false。然后通过调用fn并传入参数args执行传入的异步函数fn并将结果赋值给变量result。
接着调用setTimeout函数设置一个超时时间。当超过指定时间后timedOut的值将被设置为true并将Promise对象拒绝并返回字符串Time Limit Exceeded。
接下来监听异步函数result的完成。如果在超时时间内完成则通过resolve将结果值传递给外部Promise对象的回调函数。如果超时时间已经过去即timedOut的值为true则忽略结果并通过reject将错误传递给外部Promise对象的回调函数。
最后返回新的异步函数作为timeLimit函数的结果。 2648. 生成斐波那契数列 请你编写一个生成器函数并返回一个可以生成 斐波那契数列 的生成器对象。 斐波那契数列 的递推公式为 Xn Xn-1 Xn-2 。 这个数列的前几个数字是 0, 1, 1, 2, 3, 5, 8, 13 。 示例
输入callCount 5
输出[0,1,1,2,3]
解释
const gen fibGenerator();
gen.next().value; // 0
gen.next().value; // 1
gen.next().value; // 1
gen.next().value; // 2
gen.next().value; // 3
题解
function* fibonacciSequence() {let prev 0; //前一个值let curr 1;//当前值yield prev;yield curr;while (true) {const next prev curr;//yield next;prev curr;curr next;}
}var fibGenerator function* () {let prev 0; //前一个值let curr 1; //当前值yield prev;yield curr;while (true) {const next prev curr;//下一个值yield next;prev curr;//前一个值当前值curr next;//当前值 下一个值}
}
const fn fibGenerator()
console.log(fn);
console.log(fn.next()); //prev:0
console.log(fn.next()); //curr:1
console.log(fn.next()); //next:1 prevcurr(01) prev curr; curr next( prev:1 curr:1)
console.log(fn.next()); //next:2:prevcurr(11) prev curr; curr next( prev:1 curr:2)
console.log(fn.next()); //next:3:prevcurr(12) prev curr; curr next( prev:2 curr:3)
console.log(fn.next()); //next:5:prevcurr(23) prev curr; curr next( prev:3 curr:5)
这段代码定义了一个生成斐波那契数列的函数fibonacciSequence()。该函数通过yield关键字实现了生成器函数的特性即可以暂停执行并返回一个值然后可以从暂停的地方恢复执行。
在函数内部首先定义了prev和curr两个变量分别用来保存前一个和当前的斐波那契数。
然后通过yield关键字分别返回了prev和curr即斐波那契数列的第1和第2个数。
接下来使用while循环来生成数列的其他数。在每次循环中根据斐波那契数列的定义计算下一个数next的值然后通过yield关键字返回next。
然后将prev的值更新为当前数curr再将curr的值更新为next以便下一次循环使用。
最后通过const fibonacciGenerator fibonacciSequence将该生成器函数赋值给变量fibonacciGenerator生成一个用于产生斐波那契数列的生成器对象。
2649. 嵌套数组生成器
现给定一个整数的 多维数组 请你返回一个生成器对象按照 中序遍历 的顺序逐个生成整数。
多维数组 是一个递归数据结构包含整数和其他 多维数组。
中序遍历 是从左到右遍历每个数组在遇到任何整数时生成它遇到任何数组时递归应用 中序遍历 。
示例
输入arr [[[6]],[1,3],[]]
输出[6,1,3]
解释
const generator inorderTraversal(arr);
generator.next().value; // 6
generator.next().value; // 1
generator.next().value; // 3
generator.next().done; // true
题解
var inorderTraversal function*(arr) {for (let item of arr) {if (Array.isArray(item)) {yield* inorderTraversal(item);} else {yield item;}}
};
这段代码定义了一个名为inorderTraversal的generator函数接收一个数组作为参数。
函数开始时它通过使用for...of循环遍历输入的数组中的每个元素。如果当前元素是一个数组则递归调用inorderTraversal函数并使用yield*关键字迭代生成的值。如果当前元素不是数组则使用yield关键字返回当前元素。
这样当inorderTraversal函数被调用时它会遍历整个输入数组并按顺序yield每个元素或递归遍历内部数组。通过使用generator函数可以逐步获取数组中的元素而不是一次性返回整个数组。
2665. 计数器 II
请你写一个函数 createCounter. 这个函数接收一个初始的整数值 init 并返回一个包含三个函数的对象。
这三个函数是
increment() 将当前值加 1 并返回。decrement() 将当前值减 1 并返回。reset() 将当前值设置为 init 并返回。
示例
输入init 5, calls [increment,reset,decrement]
输出[6,5,4]
解释
const counter createCounter(5);
counter.increment(); // 6
counter.reset(); // 5
counter.decrement(); // 4
题解
var createCounter function(init) {let count init;function increment() {count;return count;}function decrement() {count--;return count;}function reset() {count init;return count;}return { //返回对象 increment,decrement,reset};
};
这段代码定义了一个函数createCounter该函数接受一个参数init作为初始值。函数内部定义了三个函数increment、decrement和reset用于增加、减少和重置计数器的值。
函数内部声明了一个变量count并将其初始化为init。函数increment将count增加1并返回count的值。函数decrement将count减少1并返回count的值。函数reset将count重置为init并返回count的值。
最后函数createCounter返回一个包含increment、decrement和reset三个方法的对象这样就创建了一个计数器对象。通过调用该对象的方法可以对计数器的值进行增加、减少和重置操作。
2666. 只允许一次函数调用
给定一个函数 fn 它返回一个新的函数返回的函数与原始函数完全相同只不过它确保 fn 最多被调用一次。
第一次调用返回的函数时它应该返回与 fn 相同的结果。第一次后的每次调用它应该返回 undefined 。
示例 输入fn (a,b,c) (a b c), calls [[1,2,3],[2,3,6]]
输出[{calls:1,value:6}]
解释
const onceFn once(fn);
onceFn(1, 2, 3); // 6
onceFn(2, 3, 6); // undefined, fn 没有被调用题解
function once(fn) {let called false;let calls 0;let result;function wrapper(...args) {if (!called) {called true;result fn(...args);calls 1;return result;} else {calls 1;return undefined;}}wrapper.calls () calls;wrapper.value () result;return wrapper;
};
这段代码定义了一个函数once它接受一个函数fn作为参数。
在函数内部定义了三个变量called、calls和result并且初始化为false、0和undefined。
函数内部还定义了一个名为wrapper的嵌套函数它使用扩展运算符收集所有参数。接下来它会判断called的值是否为false。
如果called的值为false表示函数fn还未被调用过。在这种情况下会将called的值设为true表示函数已被调用。
然后函数fn会以传入的参数被调用并将返回值赋给变量result。
接着变量calls会被递增1表示函数调用的次数。
最后函数wrapper会返回result。
如果called的值为true表示函数fn已经被调用过。在这种情况下只是将变量calls递增1并且返回undefined。
函数wrapper还定义了两个新属性calls和value。
属性calls是一个箭头函数它返回变量calls的值。
属性value也是一个箭头函数它返回变量result的值。
最后函数once会返回wrapper函数。