统计每个元素出现的次数
//reduce实现
const arr = [1,2,3,4,5,1];
const arrReduce = arr.reduce((pre,cur)=>{
pre[cur] = (pre[cur] || 0)+1;
return pre;
},{})
console.log(arrReduce)
{1: 2, 2: 1, 3: 1, 4: 1, 5: 1}
// for循环实现
const arr = [1,2,3,4,5,1];
const count = {};
for (const char of arr){
count[char] = (count[char] || 0) + 1;
}
console.log(count)
{1: 2, 2: 1, 3: 1, 4: 1, 5: 1}
// Map统计
const arr = [1,2,3,4,5,1];
const map = new Map()
arr.forEach(item=>{
map.set(item,(map.get(item) || 0 ) + 1)
})
console.log(map)
Map(5) {1 => 2, 2 => 1, 3 => 1, 4 => 1, 5 => 1}
console.log(map.entries())
MapIterator {1 => 2, 2 => 1, 3 => 1, 4 => 1, 5 => 1}
console.log(Array.from(map.entries()))
[[1,2],[2,1],[3,1],[4,1],[5,1]]
查找最大值
//reduce实现
const arr = [1,2,3,4,5,1];
const arrReduce = arr.reduce((pre,cur)=>{
return pre>cur?pre:cur
},0)
console.log(arrReduce)
5
//Math方法实现
const arr = [1,2,3,4,5,1];
const arrMax = Math.max.apply(null,arr) //最大值
const arrMin = Math.min.apply(null,arr) //最小值
console.log(arrMax,arrMin)
5 1
求对象中某个键值和
const reduceObj = [
{name:'zs',age:10},
{name:'ls',age:20},
{name:'we',age:22},
];
const arrReduce = reduceObj.reduce((pre,cur)=>{
return pre+cur.age
},0)
console.log(arrReduce)
52
数组拍平(转一维数组)
// reduce写法
const arr = [1,2,[3,[4,5]]];
const arrReduce = function(arr){
return arr.reduce((pre,cur)=>{
return pre.concat(Array.isArray(cur)?arrReduce(cur):cur)
},[])
}
console.log(arrReduce(arr))
[1, 2, 3, 4, 5]
//flat写法
const arr = [1,2,[3,[4,5]]];
const arrFlat = arr.flat(Infinity)
console.log(arrFlat)
去重
//reduce 实现
const arr = [1,2,1,2];
const arrReduce = arr.reduce((pre,cur)=>{
if(!pre.includes(cur)){
return pre.concat(cur)
}else{
return pre
}
},[])
console.log(arrReduce)
[1, 2]
//set函数实现
const arr = [1,2,1,2];
console.log(Array.from(new Set(arr)))
[1, 2]
// filter实现
const array = [1, 2, 3, 2, 1];
const uniqueArray = array.filter((item, index) => array.indexOf(item) === index);
console.log(uniqueArray);
const data = [
{id:1, name:2},
{id:1, name:2},
{id:3, name:2},
{id:4, name:2}
];
const arrReduce = data.reduce((pre,cur)=>{
if(!pre.some(item=>item.id === cur.id)){
return pre.concat(cur)
}else{
return pre
}
},[])
console.log(arrReduce)
[
{
"id": 1,
"name": 2
},
{
"id": 3,
"name": 2
},
{
"id": 4,
"name": 2
}
]
防抖
function debounce(fn,delay){
let timer = null;
return function(){
clearTimeout(timer);
timer = setTimeout(()=>{
fn.apply(this)
},delay)
}
}
document.getElementById('debounce').addEventListener('keyup', debounce(function () {
console.log('input事件被触发' + Date.now())
}, 10000))
节流
function throttle(fn,delay){
let timeLast = 0;
return function(){
let timeNow = Date.now();
if(timeNow-timeLast>delay){
fn.apply(this);
timeLast = timeNow
}
}
}
document.onscroll = throttle(function () {
console.log('scroll事件被触发了' + Date.now())
}, 2000)
reduce 递归实现树=》数组
let tree = [
{
id: 1,
name: 'Root',
children: [
{
id: 2,
name: 'Child1',
children: []
},
{
id: 3,
name: 'Child2',
children: [
{
id: 4,
name: 'Grandchild1',
children: []
}
]
}
]
}
];
function flatTreeWithReduce(nodes,parentId){
return nodes.reduce((acc,node)=>{
const {children,...rest} = node;
acc.push({...rest,parentId});
return acc.concat(flatTreeWithReduce(children,node.id))
},[])
}
console.log(flatTreeWithReduce(tree))
[
{
"id": 1,
"name": "Root"
},
{
"id": 2,
"name": "Child1",
"parentId": 1
},
{
"id": 3,
"name": "Child2",
"parentId": 1
},
{
"id": 4,
"name": "Grandchild1",
"parentId": 3
}
]
非递归方法实现树=》数组
let tree = [
{
id: 1,
name: 'Root',
children: [
{
id: 2,
name: 'Child1',
children: []
},
{
id: 3,
name: 'Child2',
children: [
{
id: 4,
name: 'Grandchild1',
children: []
}
]
}
]
}
];
const flatTree = (tree) =>{
let result = [];
let quene = [];
if(tree.length>0){
quene = [...tree]
}
while(quene && quene.length>0){
let node = quene.shift()
result.push(node)
if(node.children && node.children.length>0){
quene.push(...node.children)
}
}
return result
}
console.log(flatTree(tree))
[
{
"id": 1,
"name": "Root",
"children": [
{
"id": 2,
"name": "Child1",
"children": []
},
{
"id": 3,
"name": "Child2",
"children": [
{
"id": 4,
"name": "Grandchild1",
"children": []
}
]
}
]
},
{
"id": 2,
"name": "Child1",
"children": []
},
{
"id": 3,
"name": "Child2",
"children": [
{
"id": 4,
"name": "Grandchild1",
"children": []
}
]
},
{
"id": 4,
"name": "Grandchild1",
"children": []
}
]
超大数相加
// 使用 BigInt
function bigIntAdd(a, b) {
const result = BigInt(a) + BigInt(b);
return result.toString(); // 转为字符串返回
}
// 示例
const num1 = "123456789123456789123456789123456789";
const num2 = "987654321987654321987654321987654321";
console.log(bigIntAdd(num1, num2));
1111111111111111111111111111111111110
// 字符串逐位相加
function largeNumberAdd(a, b) {
let carry = 0;
let result = [];
// 确保 a 和 b 长度相同,不够则在前面补 0
a = a.padStart(Math.max(a.length, b.length), '0');
b = b.padStart(Math.max(a.length, b.length), '0');
// 从最后一位开始逐位相加
for (let i = a.length - 1; i >= 0; i--) {
const sum = parseInt(a[i], 10) + parseInt(b[i], 10) + carry;
carry = Math.floor(sum / 10); // 计算进位
result.unshift(sum % 10); // 取当前结果的个位
}
// 若最后还有进位,则加到结果的最前面
if (carry > 0) {
result.unshift(carry);
}
return result.join(''); // 返回最终结果
}
// 示例
const num1 = "123456789123456789123456789123456789";
const num2 = "987654321987654321987654321987654321";
console.log(largeNumberAdd(num1, num2));
1111111111111111111111111111111111110
数组交并差补集
var nums1 = [1, 2, 2, 1, 3]
var nums2 = [2, 2, 4]
// es6 交集
var a = nums1.filter(item => {
return nums2.includes(item)
})
console.log(a)
[2,2]
// es6 并集
const union = [...new Set([...nums1,...nums2])]
console.log(union)
[1,2,3,4]
// es6 差集
const difference = nums1.filter(item=>!nums2.includes(item))
console.log(difference)
[1,1,3]
const difference = nums2.filter(item=>!nums1.includes(item))
console.log(difference)
[4]
// es6 补集 相对于定义的全集来说
闭包应用
一、 实现「一个」函数,输入一个“字符串”prefix,生成一个递增的 key,以「prefix」+ _ + 数字返回, // 注意容错和边界情况,不要用全局变量 // 1. getUniqueId('my') => my_0 // 2. getUniqueId('my') => my_1 // 3. getUniqueId('my') => my_2 // 4. getUniqueId('he') => he_0 // 5. getUniqueId('he') => he_1 // 6. getUniqueId('you') => you_0 // 7. getUniqueId('my') => my_3
function createUniqueIdGenerator() {
// 使用一个对象来存储每个 prefix 的计数器
const counters = {};
// 返回一个函数,每次调用生成一个唯一 ID
return function getUniqueId(prefix) {
if (typeof prefix !== 'string' || prefix.trim() === '') {
throw new Error('Prefix must be a non-empty string');
}
// 如果该 prefix 还没有使用过,初始化计数器为 0
if (!(prefix in counters)) {
counters[prefix] = 0;
}
// 获取当前计数器值作为 id,随后递增计数器
const id = counters[prefix];
counters[prefix] += 1;
// 返回根据规则拼接的结果
return `${prefix}_${id}`;
};
}
// 使用示例
const getUniqueId = createUniqueIdGenerator();
console.log(getUniqueId('my')); // 输出: my_0
console.log(getUniqueId('my')); // 输出: my_1
console.log(getUniqueId('my')); // 输出: my_2
console.log(getUniqueId('he')); // 输出: he_0
console.log(getUniqueId('he')); // 输出: he_1
console.log(getUniqueId('you')); // 输出: you_0
console.log(getUniqueId('my')); // 输出: my_3
一个数组,出现最多的元素是哪个,以及出现次数是多少
function findMostFrequentElements(arr) {
const frequencyMap = {};
// 统计每个元素的出现次数
for (let element of arr) {
frequencyMap[element] = (frequencyMap[element] || 0) + 1;
}
// 找到最大出现次数
const maxCount = Math.max(...Object.values(frequencyMap));
// 找出所有出现次数为最大值的元素
const mostFrequentElements = [];
for (let element in frequencyMap) {
if (frequencyMap[element] === maxCount) {
mostFrequentElements.push(Number(element));
}
}
// 返回结果
return { elements: mostFrequentElements, count: maxCount };
}
// 示例:
const arr = [1, 2, 3, 4, 1, 2, 2, 3, 3, 3, 4, 4];
const result = findMostFrequentElements(arr);
console.log(`出现次数最多的元素是: ${result.elements}, 次数是: ${result.count}`);