专栏声明:只求用最简单的,容易理解的方法通过,不求优化,不喜勿喷
现给定一个对象或数组 obj,返回一个 精简对象 。精简对象 与原始对象相同,只是将包含 假 值的键移除。该操作适用于对象及其嵌套对象。数组被视为索引作为键的对象。当 Boolean(value) 返回 false 时,值被视为 假 值。
你可以假设 obj 是 JSON.parse 的输出结果。换句话说,它是有效的 JSON。
深度优先遍历
典型的分类判断 + 递归题目,前面也出现不少了,我们传入的是一个对象或数组所以我们先要用 Array.isArray 判定它是数组还是对象:
var compactObject = function(obj) {
if (obj == null || typeof obj !== 'object') {
return obj;
}
if (Array.isArray(obj)) {
const res = [];
for (let it of obj) {
const val = compactObject(it);
if (val) res.push(val);
}
return res;
}
const res = {};
const keys = Object.keys(obj);
for (let key of keys) {
const val = compactObject(obj[key]);
if (val) res[key] = val;
}
return res;
};
现给定一个函数 fn ,一个参数数组 args 和一个以毫秒为单位的超时时间 t ,返回一个取消函数 cancelFn 。
在经过 t 毫秒的延迟后,除非 先调用 cancelFn ,否则 fn 应该以 args 作为参数被调用。并且在这种情况下,fn 不应该被调用。
计数器,闭包
一个很简单的闭包的应用,创建一个计时器,在一定延迟后执行需要的执行的函数,同时返回一个函数来取消它,这个函数清除了计时器,因为闭包的特性,我们可以用这个函数来访问函数中创建的计时器。
/**
* @param {Function} fn
* @param {Array} args
* @param {number} t
* @return {Function}
*/
var cancellable = function(fn, args, t) {
let timer = setTimeout(() => {
fn(...args)
},t)
return () => { clearTimeout(timer) };
};
这题也是笔者的字节跳动面试手写题(实现一个 promise.all)
给定一个异步函数数组 functions,返回一个新的 promise 对象 promise。数组中的每个函数都不接受参数并返回一个 promise。
promise resolve 条件:
当所有从 functions 返回的 promise 都成功解析时。promise 的解析值应该是一个按照它们在 functions 中的顺序排列的 promise 的解析值数组。
promise reject 条件:
当任何从 functions 返回的 promise 被拒绝时。promise 也会被拒绝,并返回第一个拒绝的原因。
请在不使用内置的 Promise.all 函数的情况下解决。
promise、promise.all
实现一个 promise.all,这个函数 api 会在传入的所有 promise 完成后返回,我们先 new 一个 promise 作为返回值,这个 promise 的成功返回是在传入的所有 promise 执行完毕之后 ,而失败返回是在一个 promise 失败之后。
我们用一个 now 记录执行已经执行完几个了,之后遍历传入的 数组,对于每个 promise,它执行完毕后,将对应的返回值放在返回的数组执行位置,然后让 now + 1。
如果此时 now 和传入数组的长度一样,说明执行完毕了,把记录所有返回值的数组作为成功返回。
如果有任何一个传入的 promise 失败了,那么我们直接失败返回这个失败 promise 的错误信息。
/**
* @param {Array} functions
* @return {Promise}
*/
var promiseAll = async function (functions) {
let now = 0;
let re = new Array(functions.length);
return new Promise((res, rej) => {
for (let i = 0; i < functions.length; i++) {
functions[i]().then((data) => {
now++;
re[i] = data
if (now == functions.length) {
res(re);
}
},(err) => {
rej(err);
})
}
})
};
/**
* const promise = promiseAll([() => new Promise(res => res(42))])
* promise.then(console.log); // [42]
*/
现给定两个数组 arr1 和 arr2 ,返回一个新的数组 joinedArray 。两个输入数组中的每个对象都包含一个 id 字段。joinedArray 是一个通过 id 将 arr1 和 arr2 连接而成的数组。joinedArray 的长度应为唯一值 id 的长度。返回的数组应按 id 升序 排序。
如果一个 id 存在于一个数组中但不存在于另一个数组中,则该对象应包含在结果数组中且不进行修改。
如果两个对象共享一个 id ,则它们的属性应进行合并:
如果一个键只存在于一个对象中,则该键值对应该包含在对象中。
如果一个键在两个对象中都包含,则 arr2 中的值应覆盖 arr1 中的值。
归并排序、对象合并
双指针的思路,我们先对两个数组按照 id 的大小排序,之后从两个数组的第一位开始合并:
/**
* @param {Array} arr1
* @param {Array} arr2
* @return {Array}
*/
var join = function (arr1, arr2) {
arr1.sort((a, b) => a.id - b.id);
arr2.sort((a, b) => a.id - b.id);
let res = [];
let j = 0;
for (var i = 0; i < arr1.length; i++) {
if (j == arr2.length) {
break;
}
let id1 = arr1[i].id;
if (arr2[j].id == id1) {
res.push(Object.assign(arr1[i], arr2[j]));
j++;
} else if (arr2[j].id < id1) {
res.push(arr2[j]);
j++;
i--;
} else {
res.push(arr1[i]);
}
}
while (i < arr1.length) {
res.push(arr1[i]);
i++;
}
while (j < arr2.length) {
res.push(arr2[j]);
j++;
}
return res.sort((a, b) => a.id - b.id);
};
给定两个 promise 对象 promise1 和 promise2,返回一个新的 promise。promise1 和 promise2 都会被解析为一个数字。返回的 Promise 应该解析为这两个数字的和。
promise
考察 promise 的基本概念。使用 promise.then 来等待两个 promise 返回,需要在一个 promise 返回后再去处理论一个 promise ,或者用 promise.all 来处理他们,在两个 promise 的返回值都拿到之后,相加返回作为新的 promise 的成功返回即可
/**
* @param {Promise} promise1
* @param {Promise} promise2
* @return {Promise}
*/
var addTwoPromises = async function(promise1, promise2) {
return new Promise((res,rej) => {
promise1.then((res1) => {
promise2.then((res2) => {
res(res1 + res2)
})
})
})
};
/**
* addTwoPromises(Promise.resolve(2), Promise.resolve(2))
* .then(console.log); // 4
*/
给定一个数组 arr 和一个函数 fn,返回一个排序后的数组 sortedArr。你可以假设 fn 只返回数字,并且这些数字决定了 sortedArr 的排序顺序。sortedArr 必须按照 fn 的输出值 升序 排序。
你可以假设对于给定的数组,fn 不会返回重复的数字。
sort
简单题略… 考察 sort 这个 api 的使用,它传入两个值,你可以对这两个值进行处理,然后在进行比较逻辑
/**
* @param {Array} arr
* @param {Function} fn
* @return {Array}
*/
var sortBy = function (arr, fn) {
return arr.sort((a, b) => fn(a) - fn(b));
};