本文题目来源于leetcode、掘金等各大网站资源,纯属记录用来学习。一直记录更新中。。。
1.小蝌蚪按顺序找妈妈
有两组数组,第二组根据第一组顺序一一对应分配给第一组数组,结果返回对象数组形式。
const mom = ['张三', '李四', '老王', '李四', '张三', '老王']
const son = [1, 23, 5, 9, 12, 4]
结果:{ '张三': [ 1, 12 ], '李四': [ 23, 9 ], '老王': [ 5, 4 ] }
const findMom = (mon, son) => {
return mom.reduce((pre, cur, index, arr) => { // pre: 上一次调用回调返回的值,或者是提供的初始值
- if (!pre[cur]) { // cur: 当前元素
- pre[cur] = [] // index: 当前元素的索引
- }
+ pre[cur] = pre[cur] || []
for (let i = 0; i < son.length; i++) {
if (index === i) {
pre[cur].push(son[i])
}
}
return pre
}, {}) // 初始值
}
console.log(findMom(mom, son))
2.姓名和分数对应
const arr = [
{name: '小明', score: 10},
{name: '小红', score: 10},
{name: '小明', score: 10},
{name: '小红', score: 40}
]
结果:
[
{ name: '小明', value: [ 10, 10 ] },
{ name: '小红', value: [ 10, 40 ] }
]
const newArr = arr.reduce((ret, {name, score}) => {
(ret[name] = ret[name] || {
name: name,
value: []
}).value.push(score)
return ret
}, {})
console.log(Object.values(newArr))
3.找出数组中的字符串公共因子
const strs = ['flower', 'flow', 'flight']
结果:fl
let longestCommonPrefix = strs => {
if (strs.length === 0) return ''
let ans = strs[0]
for (let i = 1; i < strs.length; i++) {
let j=0
for(; j < ans.length && j < strs[i].length; j++) {
if (ans[j] !== strs[i][j]) break
}
ans = ans.substr(0, j)
if (ans === '') return ans
}
return ans
}
console.log(longestCommonPrefix(strs))
4.数组对象按照年龄分组
const arr = [
{name: '小明', age: 18},
{name: '小红', age: 19},
{name: '小东', age: 18},
{name: '老王', age: 26},
{name: '小林', age: 19},
{name: '小王', age: 18}
]
结果:{ '18': [ '小明', '小东', '小王' ], '19': [ '小红', '小林' ], '26': [ '老王' ] }
const ageGroup = (arr, key) => {
return arr.reduce((pre,cur) => {
pre[cur[key]] = pre[cur[key]] || []
pre[cur[key]].push(cur['name'])
return pre
}, {})
}
console.log(ageGroup(arr, 'age'))
5.从一个数组中找出两个数和为一个数,找不到返回[]
const arr = [1, 5, 10, 12, 8]
total: 15
结果:[ 5, 10 ]
const findTotal = (arr, total) => {
arr.sort((a, b) => a - b)
for (let i = 0, j = arr.length - 1; i < j;) {
let nums = arr[i] + arr[j]
if (nums === total) {
return [arr[i], arr[j]]
} else if (nums < total) {
i++
} else {
j--
}
}
return []
}
console.log(findTotal(arr, 15))
6.删除排序数组中的重复项,返回数组的长度
const arr = [1, 1, 2]
结果: 2
let removeDuplicates = arr => {
let count = 0
let n = arr.length
for (let i = 0; i < n; i++) {
if (arr[i] != arr[i+1]) {
arr[i-count] = arr[i]
} else {
count++
}
}
return n-count
}
console.log(removeDuplicates(arr))
7.找出数组中重复的数(一个就行)
const arr = [0, 11, 30, 11, 15]
结果:11
let findRepeatNumber = arr => {
let s = new Set() // set自动忽略重复元素
for (let i in arr){
let curLenth = s.size
s.add(arr[i])
if (s.size === curLenth) return arr[i]
}
}
或者(双for):
let findRepeatNumber = arr => {
for (let i = 0; i < arr.length - 1; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) return arr[i]
}
}
}
console.log(findRepeatNumber(arr))
8.在两个数组中找出重复值
const arr1 = [5, 9, 6, 2, 3]
const arr2 = [6, 9, 3, 4, 1, 8]
最土:
const findSameVal1 = (arr1, arr2) => {
let arr = []
for (let i = 0; i < arr1.length; i++) {
for (let j = 0; j < arr2.length; j++) {
if (arr1[i] === arr2[j]) arr.push(arr1[i])
}
}
return arr
}
有点意思(坑:万一一个数组里有很多重复的,主要学习它的思维):
const findSameVal2 = (arr1, arr2) => {
let arr = arr1.concat(arr2)
let arr3 = []
arr.sort((a, b) => a -b)
for (let i = 0; i < arr.length; i++) {
if (arr[i] === arr[i+1]) arr3.push(arr[i])
}
}
有内味了:
const findSameVal3 = (arr1, arr2) => {
let arr = []
for (let i = 0; i < arr1.length; i++) {
arr2.some((item) => { // 类似filter,find等等
if (item === arr1[i]) arr.push(item)
})
}
return arr
}
9.数组按规则组合成对象(常用于对后端返回的值做第二次操作符合自己使用)
const list = [ {city: '北京', area: '天安门'}, {city: '北京', area: '颐和园'}, {city: '上海', area: '东方明珠'}]
结果:
let obj = {
'北京': [{city: '北京', area: '天安门'}, {city: '北京', area: '颐和园'}],
'上海': [{city: '上海', area: '东方明珠'}]
}
脑壳疼有点low,期待大佬的‘妙’
const goupBy = (list, city) => {
let obj = {}
let arr = []
list.forEach(e => {
if (arr.indexOf(e.city) < 0) { // 取出city
arr.push(e.city)
}
})
for (let i in arr) { // 对象格式
obj[arr[i]] = []
}
for (let i = 0; i < list.length; i++) { // 对象往里添加选项
for (let j in obj) {
if (j === list[i].city) {
obj[j].push(list[i])
}
}
}
return obj
}
console.log(goupBy(list, 'city'))
10.删除字符串中的所有相邻重复项
解题思路: 遍历字符串,依次入栈,入栈时判断与栈头元素是否一致,如果一致,即这两个元素相同相邻,则需要将栈头元素出栈,并且当前元素也无需入栈。
const str = 'abbaca'
结果:
'ca'
const removeDuplicates = str => {
const arr = []
for (const i of str) { // 字符串遍历
if (arr.length && arr[arr.length - 1] === i) { // 入栈与栈头是否一致
arr.pop() // 删除最后一个元素
} else {
arr.push(i)
}
}
return arr.join('') // 字符串变数组用split() 数组变字符串用join()
}
console.log(removeDuplicates(str))
11.数组去重
棕小渐(解锁多种JavaScript数组去重姿势):juejin.cn/post/684490…
const arr = [1, 2, 0, 1, 2, 5, 5.2]
结果:
[1, 2, 0, 5, 5.2]
方法一:(map)
const unique = arr => {
const map = new Map()
return arr.filter(item => {
return !map.has(item) && map.set(item, 1)
})
}
console.log(unique(arr))
方法二:(es6的set)
const unique = arr => [...new Set(arr)]
12.字符串反转
const str = 'jacklove'
结果:
evolkcaj
const reverse = str => {
let arr = []
let i = str.length
while (i > -1) {
i--
arr.push(str[i])
}
return arr.join('')
}
console.log(reverse(str))
13.微宏任务执行顺序
setTimeout(() => {
console.log(3)
new Promise((resolve, reject) => {
console.log(4)
resolve()
}).then(() => {
setTimeout(() => {
console.log(5)
}, 0)
console.log(6)
})
}, 0)
new Promise((resolve, reject) => {
resolve()
}).then(() => {
console.log(8)
return new Promise((resolve1, reject) => {
console.log(9)
setTimeout(() => {
console.log(10)
}, 0)
resolve1()
})
}).then(() => {
console.log(11)
})
new Promise((resolve2, reject) => {
resolve2()
}).then(() => {
console.log(13)
})
结果:8 9 13 11 3 4 6 10 5
new Promise自动执行,执行完再执行.then()里面,定时器最后执行
14.赋值,指向问题
let a = {
name: '德莱文',
age: 12
}
const test = b => {
b.age = 18
let c = {
name: '文森特',
age: 25
}
b = c
console.log(b) // { name: '文森特', age: 25 }
b.age = 11
console.log(c) // { name: '文森特', age: 11 }
return b
}
let d = test(a)
console.log(d) // { name: '文森特', age: 11 }
console.log(a) // { name: '德莱文', age: 18 }
let a = {n: 1}
let b = a
a.x = a = {n: 2} // 相当于 a.x = {n: 2} a = {n: 2}
console.log(a) // {n: 2}
console.log(b) // {n: 1, x: {n: 2}}
// 当执行完b指向a时,再执行a.x(点符号优先执行),此时b={n: 1, x: undefined}。复制操作a.x = {n: 2},b指向a那么b={n: 1, x: {n: 2}},最后执行a={n: 2}
15.找出数组 arr 中重复出现过的元素
const arr = [1, 2, 4, 4, 3, 3, 1, 5, 3]
结果:
[1, 4, 3]
const duplicates = arr => {
let list = []
arr.forEach(e => {
if (arr.indexOf(e) !== arr.lastIndexOf(e) && list.indexOf(e) === -1) {
list.push(e)
}
})
return list
}
console.log(duplicates(arr))
16.数组对象去重关键值
const list = [
{name: 'a', age: 1},
{name: 'b', age: 2},
{name: 'c', age: 2},
{name: 'a', age: 3},
{name: 'c', age: 2}
]
结果:
1.关键值是name时:
const list = [
{name: 'a', age: 1},
{name: 'b', age: 2},
{name: 'c', age: 2}
]
2.关键值是age时:
const list = [
{name: 'a', age: 1},
{name: 'b', age: 2},
{name: 'a', age: 3}
]
// const duplicationJson = (list, key) => {
// let map = {} // 对key进行计数,如果一个就是不重复
// return list.filter(item => {
// let value = item[key]
// if (!map[value]) {
// map[value] = 1
// } else {
// map[value] += 1
// }
// return map[value] === 1
// })
// }
const duplicationJson = (list, key) => {
let map = {}
// 判断map是否有这个key不存在则写入map并赋值true,若存在不写入
return list.filter(item => !map[item[key]] && (map[item[key]] = true))
}
console.log(dup(duplicationJson, 'name'))
17.偏平化处理tree
let arr = [
{id: 1, name: '部门1', pid: 0},
{id: 2, name: '部门2', pid: 1},
{id: 3, name: '部门3', pid: 1},
{id: 4, name: '部门4', pid: 3},
{id: 5, name: '部门5', pid: 4},
]
结果:
[
{id: 1, name: '部门1', pid: 0
children: [
{id: 2, name: '部门2', pid: 1, children: []},
{id: 3, name: '部门3', pid: 1, children: [
{id: 4, name: '部门4', pid: 3, children: [
{id: 5, name: '部门5', pid: 4, children}
]}
]}
]
}
]
function arrayToTree(arr) {
let result = []
let itemMap = {}
for (let item of arr) {
let id = item.id
let pid = item.pid
itemMap[id] = {
...item,
children: []
}
let treeItem = itemMap[id]
if (!itemMap[pid]) {
result.push(treeItem)
} else {
itemMap[pid].children.push(treeItem)
}
}
return result
}
18.
(我是970)[juejin.cn/post/698510…]
实现一个EatMan
说明:实现一个EatMan,EatMan可以有以下一些行为
示例:
1. EatMan('Hank')
Hi! This is Hank!
2. EatMan('Hank').eat('dinner').eat('supper') // 链式调用
Hi! This is Hank!
Eat dinner~
Eat supper~
3. EatMan('Hank').eat('dinner').eatFirst('lunch') // 输出顺序
Eat lunch~
Hi! This is Hank!
Eat dinner~
4. EatMan('Hank').eat('dinner').eatFirst('lunch').eatFirst('breakfast') // 插队输出
Eat breakfast~
Eat lunch~
Hi! This is Hank!
Eat dinner~
class MyEatMan {
constructor(name) {
this.name = name
// 任务队列,将需要执行的函数入队
this.tasks = []
// 第一个任务
const task = this.printName(this.name)
// 放入任务队列
this.tasks.push(task)
// 为了保证任务都能在进队完毕之后再执行,创建一个宏任务,让执行任务的时机放到 下一个事件循环里
let self = this
setTimeout(function () {
// console.log('tasks', self.tasks)
self.run()
}, 0)
}
printName(name) {
let self = this
return function () {
console.log(`Hi! This is ${name}!`)
self.run()
}
}
// eat函数,每次调用都入队一个任务,而且还能实现链式调用
eat(thing) {
let self = this
const task = function () {
console.log(`Eat ${thing}~`)
self.run()
}
this.tasks.push(task)
return this
}
// eatFirst函数,谁最后初始化,谁先执行,而且还能实现链式调用
eatFirst(thing) {
let self = this
const task = function () {
console.log(`Eat ${thing}~`)
self.run()
}
// 插入到队列的头部
this.tasks.unshift(task)
return this
}
// run执行任务
run() {
// 出队
const currTask = this.tasks.shift()
// 执行
currTask && currTask()
}
}
function EatMan(name) {
return new MyEatMan(name)
}
19.金钱数字分隔
const NumberSplit = num => {
const decimal = String(num).split('.')[1] || '' // 小数
let tempArr = []
const revNumArr = String(num).split('.')[0].split('').reverse() // 倒序
for (let i in revNumArr) {
tempArr.push(revNumArr[i])
if ((i + 1) % 3 === 0 && i != revNumArr.length - 1) {
tempArr.push(',')
}
}
const integer = tempArr.reverse().join('') // 整数部分
return decimal ? integer + '.' + decimal : integer
}
console.log(NumberSplit(44651223.56)) // 44,651,223.56
20.数组分类去重
const b = [
{name: '颜色', value: '黑色'},
{name: '尺寸', value: 'xxl'},
{name: '颜色', value: '白色'},
{name: '大小', value: '小'},
{name: '尺寸', value: 'xxl'}
]
let hash = {}
let i = 0
let res = []
b.forEach(item => {
let { name, value } = item
if (hash[name]) {
let list = res[hash[name] - 1].value
if (list.indexOf(value) === -1) { // 相同值不添加
list.push(value)
}
} else {
hash[name] = ++i && res.push({name, value: [value]})
}
})
console.log(res)
[ { name: '颜色', value: [ '黑色', '白色' ] },
{ name: '尺寸', value: [ 'xxl' ] },
{ name: '大小', value: [ '小' ] }
]