简介
有时我发现了一些聪明的、有趣的或者被忽视的方法来解决JavaScript中的某些问题。这是我第一次尝试捕捉其中的一些项目,随机的,没有特定的顺序。我将尝试把这些想法表述为类似于stackoverflow的问题/答案,因为我们经常在谷歌上搜索我们正在试图解决的问题。
我怎样才能只保留一个数组中也在另一个数组中的项目?
我们可能会想用数组includes 的方法来解决这个问题,但这将是相当低效的。
const arr1 = [1, 2, 3, 2, 4, 5, 6];
const arr2 = [2, 4, 6];
const filtered = arr1.filter((el) => arr2.includes(el));
这里最大的效率问题是它是一个循环中的循环(filter 循环到arr1 ,includes 循环到arr2 ,以获得arr1 的每个元素)。对于一个更有效的解决方案,可以考虑使用Set ,以实现哈希表的效率。
const arr1 = [1, 2, 3, 2, 4, 5, 6];
const arr2 = [2, 4, 6];
const arr2Set = new Set(arr2);
const filtered = arr1.filter((el) => arr2Set.has(el));
现在,你通过arr1 迭代一次(有过滤器)和arr2 迭代一次(当创建你的Set )。请注意,在这种情况下,只有当数组达到~100个元素的范围时,创建一个新的Set才比使用includes 更有效。如果你要优化性能,一定要用你预期的数组大小来做性能测试!
我如何翻转对象中的键和值?
我见过用Object.entries 和Arrayreduce 的组合来完成这个任务,但我认为一个简单的for...in 循环是完成这个任务的最有效方法。
const myObj = {
a: 'aKey',
b: 'bKey',
c: 'cKey',
};
const reversed = {};
for (key in myObj) {
reversed[myObj[key]] = key;
}
我如何在一个范围内生成一个随机的整数,但不包括一个整数的子集?
为了完成这个任务,让我们创建一个函数,接收开始的整数、结束的整数和一个要排除的整数阵列。为了提高效率,我们用一个Set 创建一个excludeLookup 。然后我们从min 到max 的值做一个for 循环,只在项目不在我们的excludeLookup 集中时才把它们添加到一个nums 数组中。最后,我们通过在我们的nums 数组中选择一个随机的元素来生成一个随机数!
function randomInt(min, max, exclude) {
const nums = [];
const excludeLookup = new Set(exclude);
for (let i = min; i <= max; i++) {
if (!excludeLookup.has(i)) nums.push(i);
}
if (nums.length === 0) return false;
const randomIndex = Math.floor(Math.random() * nums.length);
return nums[randomIndex];
}
console.log(randomInt(1, 5, [2, 3]));
当我不知道父对象是否存在时,我怎样才能安全地访问一个对象的子属性?
当我们还在等待可选链的广泛实现时,我们可以实现一个safelyGet 函数,让我们访问深层对象的道具或指定一个安全的回退。
function safelyGet(obj, path, fallback = undefined) {
let needle = obj;
const found = path.every((el) => {
if (needle[el] === undefined) return false;
needle = needle[el];
return true;
});
return found ? needle : fallback;
}
// Usage
const myObj = {
user: {
bio: {
age: 25,
},
},
};
const age = safelyGet(myObj, ['user', 'bio', 'age']);
console.log(age); // 25
const permissions = safelyGet(myObj, ['user', 'auth', 'permissions'], 'none');
console.log(permissions); // "none"
我如何通过一个任意的起始字符串来过滤一个项目列表?
也许你有一个城市列表,你想通过某个搜索字符串来过滤,但你只想匹配城市列表的起始部分。为了达到这个目的,你可以使用indexOf 和filter!
const cities = [
'Barcelona',
'Berlin',
'Bucharest',
'Budapest',
'Dublin',
'Lisbon',
];
const search = 'bu';
const filtered = cities.filter(
(city) => city.toLowerCase().indexOf(search.toLowerCase()) === 0
);
console.log(filtered); // ["Bucharest", "Budapest"];
如何才能真正实现数组的洗牌?
我发现洗数组的最好方法是遍历数组中的每个元素,并从数组中随机选择另一个元素与之交换。这个方法在javascript.info网站上有详细介绍,如下图所示。请注意,这个特殊的实现是创建一个新的数组,而不是修改输入数组。
function shuffle(oldArray) {
const array = [...oldArray];
for (let i = array.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}