把遇到的记录下来,如果大家手里也有手写代码的题可以分享哈,会不断的更新
字符串相关
String.trim()实现
let str=' 1 2 3 5 ' //1 2 3 5
let start,end
for(let i=0;i<str.length;i++){
if(str[i]!==' '){
start=i
break;
}
}
for(let i=str.length-1;i>0;i--){
if(str[i]!==' '){
end=i
break;
}
}
let res=str.substring(start,end+1)
new 函数实现
function newInstance(constructor, ...args) {
// 创建一个空对象,且 __proto__ 指向 constructor.prototype
const obj = Object.create(constructor.prototype);
// 执行构造函数并绑定 this 到新对象上
const result = constructor.apply(obj, args);
// 如果构造函数返回了一个对象,则返回该对象
if (result && (typeof result === "object" || typeof result === "function")) {
return result;
}
// 否则返回新对象
return obj;
}
// 示例使用
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log(`Hello, I'm ${this.name}.`);
};
const person1 = newInstance(Person, "Allen");
person1.greet(); // 输出 "Hello, I'm Allen."
手写intanceof实现原理
function myInstanceof(left,right){
//获取对象的原型
let proto=Object.getPrototypeOf(left)
//获取构造函数的prototype对象
let prototype=right.prototype
//判断构造函数的prototype对象是否在对象的原型链上
while(true){
if(!proto) return false
if(proto===prototype) return true
//如果没有找到,就继续从其原型上找,Object.getPrototypeOf方法来获取指定对象的原型
proto=Object.getPrototypeOf(proto)
}
}
数组去重
方法一 原型上手写方法
Array.prototype.unique = function() {
let uniqueArray = [];
for(let i = 0; i < this.length; i++) {
if(uniqueArray.indexOf(this[i]) === -1) {
uniqueArray.push(this[i]);
}
}
return uniqueArray;
}
let array = [1, 2, 2, 3, 4, 4, 5];
let uniqueArray = array.unique();
console.log(uniqueArray); // 输出 [1, 2, 3, 4, 5]
方法二 es6 Set
function unique(arr) {
return Array.from(new Set(arr));
}
let array = [1, 2, 2, 3, 4, 4, 5];
let uniqueArray = unique(array);
console.log(uniqueArray); // 输出 [1, 2, 3, 4, 5]
方法三 对象key唯一
function unique(arr) {
let hashTable = {};
let uniqueArray = [];
for(let i = 0; i < arr.length; i++) {
if(!hashTable[arr[i]]) {
hashTable[arr[i]] = true;
uniqueArray.push(arr[i]);
}
}
return uniqueArray;
}
let array = [1, 2, 2, 3, 4, 4, 5];
let uniqueArray = unique(array);
console.log(uniqueArray); // 输出 [1, 2, 3, 4, 5]
方法四 includes
function unique(arr) {
let uniqueArray = [];
for (let i = 0; i < arr.length; i++) {
if (!uniqueArray.includes(arr[i])) {
uniqueArray.push(arr[i]);
}
}
return uniqueArray;
}
let array = [1, 2, 2, 3, 4, 4, 5,[1,2,3]];
let uniqueArray = unique(array);
console.log(uniqueArray);
数组扁平化
//输入 var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
//输出 [1,2,3,4,5,6,7,8,9,10,11,12]
方法一 普通遍历
function flat(arr){
if(Object.prototype.toString.call(arr) != "[object Array]"){return false};
let res = [];
for(var i=0;i<arr.length;i++){
if(arr[i] instanceof Array){
res = res.concat(flat(arr[i]))
}else{
res.push(arr[i])
}
}
return res;
};
var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
flat(arr);
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
方法二(递归+扩展运算符)
function flat(arr){
if(Object.prototype.toString.call(arr) != "[object Array]"){return false};
let res=[];
arr.map(item=>{
if(item instanceof Array){
res.push(...flat(item));
}else{
res.push(item)
}
});
return res;
};
var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
flat(arr);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
方法三 (递归+reduce)
function flat(arr){
if(Object.prototype.toString.call(arr) != "[object Array]"){return false};
let res = arr.reduce((prev,cur)=>{
return prev.concat(Array.isArray(cur) ? flat(cur) : cur)
},[])
return res;
};
var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
flat(arr);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
方法四 (toString+split) 推荐
var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
var arr1 = arr.toString().split(',').map((val)=>{
return parseInt(val)
});
console.log(arr1);
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
方法五 递归
let arr = [[1, 2], 3, [[[4], 5]]];
function flat(arr) {
return [].concat(
...arr.map(x => Array.isArray(x) ? flat(x) : x)
)
};
flat(arr);// [1,2,3,4,5]
方法六 (递归+扩展运算符)
function flat(arr){
if(Object.prototype.toString.call(arr) != "[object Array]"){return false};
let res=[];
arr.map(item=>{
if(item instanceof Array){
res.push(...flat(item));
}else{
res.push(item)
}
});
return res;
};
var arr = [1,2,[3,4,5,[6,7,8],9],10,[11,12]];
flat(arr);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
查找
实现一个查找文章中出现频率最高的单词的方法
function findMostFrequentWord(text) {
// 将文本转换为小写并分割为单词数组
let words = text.toLowerCase().split(/\W+/);
// 创建一个对象来存储每个单词的频率
let wordFreq = {};
// 遍历单词数组并计算每个单词的频率
for (let i = 0; i < words.length; i++) {
if (wordFreq[words[i]]) {
wordFreq[words[i]]++;
} else {
wordFreq[words[i]] = 1;
}
}
// 创建一个数组来存储频率最高的几个单词
let topWords = Object.keys(wordFreq).sort((a, b) => wordFreq[b] - wordFreq[a]);
// 返回频率最高的单词
return topWords[0];
}
// 测试代码
let text = "The quick brown fox jumps over the lazy dog. The dog is lazy. Fox jumps over dog.";
console.log(findMostFrequentWord(text)); // 输出 "the"
call apply bind
const person1={
name:'ludan',
say:function(n1,n2){
console.log(this.name,n1+n2)
}
}
const person2={
name:'123'
}
Function.prototype.myCall=function(context,...args){
if(typeof this!='function'){
throw new TypeError('error')
}
context=context||window
context.fn=this
let result=context.fn(...args)
delete context.fn
return result
}
// const arr=[2,3,4,5,6]
person1.say.myCall(person2)
apply
const person1={
name:'ludan',
say:function(n1,n2){
console.log(this.name,n1+n2)
}
}
const person2={
name:'123'
}
Function.prototype.myApply=function(context,arrArgs){
if(typeof this!='function'){
throw new TypeError('error')
}
context=context||window
context.fn=this
let result=context.fn(...arrArgs)
delete context.fn
return result
}
const arr=[2,3,4,5,6]
person1.say.myApply(person2,[10,20])
bind
const person1={
name:'ludan',
say:function(n1,n2){
console.log(this.name,n1+n2)
}
}
const person2={
name:'123'
}
Function.prototype.myBind = function(context, ...args) {
// 判断调用对象是不是函数
if(typeof this !== "function"){
throw new TypeError('error');
}
// 如果没有传入上下文对象,则默认为全局对象window
context = context || window
// 保存原始函数的引用,this就是要绑定的函数
const _this = this
// 返回一个新的函数作为绑定函数
return function fn(...innerArgs) {
// 判断返回出去的函数有没有被new
if(this instanceof fn){
return new _this(...args, ...innerArgs);
}
// 使用 apply 方法将原函数绑定到指定的上下文对象上
return _this.apply(context, [...args, ...innerArgs]);
};
};
let person=person1.say.myBind(person2)
person(1,2)
防抖 节流
防抖(debounce)是一种在一定时间内只触发一次的技术,常用于处理高频事件,例如输入框的连续搜索。以下是一个适合面试的防抖代码示例:
function debounce(func, wait) {
let timeout;
return function() {
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(this, arguments);
}, wait);
};
}
解释:
debounce函数接受两个参数:要防抖的函数func和等待时间wait。- 函数内部创建一个
timeout变量,用于存储定时器的引用。 - 返回一个新函数,该函数在调用时首先会清除之前的定时器,然后设置一个新的定时器。
- 在定时器回调中,调用原始函数
func并传入当前上下文和参数。 - 在等待时间
wait内,如果再次调用返回的函数,则清除之前的定时器并重新设置。 - 当等待时间过后,如果之前没有再次调用返回的函数,则定时器回调执行原始函数
func。
该代码实现了防抖功能,并在等待时间内只触发一次原始函数。如果需要在面试中展示自己的代码能力,可以将此代码写在纸上或黑板上,并解释每一步的操作和实现原理。
节流 第一版
节流(throttling)是一种限制单位时间内触发次数的技术,常用于处理高频事件,例如滚动事件。以下是一个适合面试的节流代码示例:
function throttle(func, limit) {
let lastCall = 0;
return function() {
const now = Date.now();
if (now - lastCall < limit) {
return;
}
lastCall = now;
func.apply(this, arguments);
};
}
解释:
throttle函数接受两个参数:要节流的函数func和限制时间间隔limit。- 函数内部创建一个
lastCall变量,用于记录上次调用的时间戳。 - 返回一个新函数,该函数在调用时首先获取当前时间戳
now,然后与上次调用时间戳lastCall进行比较。 - 如果当前时间与上次调用时间差小于限制时间间隔
limit,则不执行任何操作,直接返回。 - 如果当前时间与上次调用时间差大于等于限制时间间隔
limit,则更新lastCall为当前时间戳,并调用原始函数func,传入当前上下文和参数。 - 该代码实现了节流功能,在限制时间间隔内只触发一次原始函数。如果需要在面试中展示自己的代码能力,可以将此代码写在纸上或黑板上,并解释每一步的操作和实现原理。
第二版定时器
function throttle(func, limit) {
let timer = null;
return function() {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, arguments);
timer = null;
}, limit);
}
};
}
解释:
throttle函数接受两个参数:要节流的函数func和限制时间间隔limit。- 函数内部创建一个
timer变量,用于存储定时器的引用。 - 返回一个新函数,该函数在调用时会首先检查
timer是否为空。 - 如果
timer为空,则设置一个定时器,在limit时间后调用原始函数func,并传入当前上下文和参数。 - 如果
timer不为空,则表示已经在等待时间内触发了多次函数调用,因此不执行任何操作。 - 当定时器回调执行完原始函数
func后,将timer设置为空,以便在下一次触发时重新设置定时器。
手写倒计时
let countdown = 10;
function count() {
console.log(countdown);
if (countdown-- !== 0) {
setTimeout(count, 1000);
} else {
console.log('倒计时结束');
}
}
count();
前端js--30-计时器
// setTimeout
function count(start, end) {
if(start <= end){
console.log(start);
start++;
st = setTimeout(function(){count(start, end)}, 100);
}
return {
cancel: function(){clearTimeout(st);}
}
手写深度拷贝
//使用递归实现深拷贝
function deepClone(obj) {
//判断拷贝的obj是对象还是数组
var objClone = Array.isArray(obj) ? [] : {};
if (obj && typeof obj === "object") { //obj不能为空,并且是对象或者是数组 因为null也是object
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === "object") { //obj里面属性值不为空并且还是对象,进行深度拷贝
objClone[key] = deepClone(obj[key]); //递归进行深度的拷贝
} else {
objClone[key] = obj[key]; //直接拷贝
}
}
}
}
return objClone;
}
let obj = {
a: [1, 2, 3,[2,3,5]],
b: 2,
c: 3,
d: { a: "1", b: "2" },
};
let a=deepClone(obj)
console.log(a)
手撕快排
function quickSort(arr, left = 0, right = arr.length - 1) {
if (left < right) {
let pivotIndex = partition(arr, left, right);
quickSort(arr, left, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, right);
}
return arr;
}
function partition(arr, left, right) {
let pivot = arr[right];
let i = left;
for (let j = left; j < right; j++) {
if (arr[j] < pivot) {
[arr[i], arr[j]] = [arr[j], arr[i]];
i++;
}
}
[arr[i], arr[right]] = [arr[right], arr[i]];
return i;
}
let arr = [9, -3, 5, 2, 6, 8, -6, 1, 3];
console.log(quickSort(arr)); // [-6, -3, 1, 2, 3, 5, 6, 8, 9]
利用setTimeout实现setInterval
function setIntervalUsingSetTimeout(callback, delay) {
function loop() {
callback();
setTimeout(loop, delay);
}
setTimeout(loop, delay);
}
// 使用方式
setIntervalUsingSetTimeout(function() {
console.log("这是每隔两秒执行一次的消息");
}, 2000);
EventBus
class EventBus {
constructor() {
this.bus = {};
}
$on(name, fn) {
if (this.bus[name]) {
this.bus[name].push(fn);
} else {
this.bus[name] = [fn];
}
}
$emit(name, ...args) {
if (this.bus[name]) {
let tasks = this.bus[name].slice();
tasks.forEach((callback) => {
callback(...args);
});
}
}
$off(name, fn) {
let task = this.bus[name];
if (task) {
this.bus[name] = this.bus[name].filter(
(cb) => cb !== fn
); // 过滤掉要取消的回调函数
}
}
}
// 创建全局事件总线对象
const eventBus = new EventBus();
const callback1 = (data) => {
console.log("Callback 1:", data);
};
const callback2 = (data) => {
console.log("Callback 2:", data);
};
// 订阅事件
eventBus.$on("event1", callback1);
eventBus.$on("event1", callback2);
// 发布事件
eventBus.$emit("event1", "Hello, world!");
// 输出:
// Callback 1: Hello, world!
// Callback 2: Hello, world!
// 取消订阅事件
eventBus.$off("event1", callback1);
// 发布事件
eventBus.$emit("event1", "Goodbye!");
实现一个简单的双向绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input id="inputElement" type="text">
<div id="outputElement"></div>
</body>
</html>
<script>
let state = {}
const inputElement = document.getElementById('inputElement')
const outputElement = document.getElementById('outputElement')
Object.defineProperty(state, 'value', {
configurable: true,
enumerable: true,
get: () => {
console.log('get value')
},
set: (newValue) => {
console.log('set value: ', newValue)
inputElement.value = newValue
outputElement.innerHTML = newValue
}
})
inputElement.addEventListener('keyup', (event) => {
state.value = event.target.value
})
</script>
coder.sleep().print1().print2()
function Coder () {
}
Coder.prototype = {
sleep() {
console.log(`sleep`);
return this
},
print1() {
console.log('print1!');
return this
},
print2() {
console.log('print2');
return this
},
}
const coder = new Coder()
coder.sleep().print1().print2()
类的实现
class Coder {
print1() {
console.log("Printing from print1 method");
return this;
}
print2() {
console.log("Printing from print2 method");
return this;
}
sleep() {
console.log("sleep");
return this;
}
}
const coder = new Coder();
coder.sleep().print1().print2()
实现代码3秒后执行下面代码
const arr = [[1,2],[3,4],[5,6],[7,8]]
function arrreadce(arr){
return arr.reduce((pre,cur)=>{
return pre.concat(Array.isArray(cur)?arrreadce(cur):cur)
},[])
}
function delay(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, time)
})
}
(async function (){
await delay(3000)
console.log('ok')
})()
手写获取url 获取链接参数
// 输入: www.nowcoder.com?key=1&key=2&key=3&test=4#hehe key
// 输出: [1, 2, 3]
function getUrlParam(sUrl, sKey) {
var paramArr = sUrl.split('?')[1].split('#')[0].split('&'); // 取出每个参数的键值对放入数组
const obj = {};
paramArr.forEach(element => {
const [key, value] = element.split('='); // 取出数组中每一项的键与值
if(obj[key] === void 0){ // 表示第一次遍历这个元素,直接添加到对象上面
obj[key]=value
} else{
obj[key]=[].concat(obj[key],value); // 表示不是第一次遍历说明这个键已有,通过数组存起来。
}});
return sKey===void 0? obj:obj[sKey]||'' // 如果该方法为一个参数,则返回对象。
//如果为两个参数,sKey存在,则返回值或数组,否则返回空字符。
}
let url = 'https://example.com/?name=John&age=30&city=New%20York';
let params = url.split('?')[1]; // 获取URL中问号后的部分
let extractParams = {};
params.split('&').forEach(function(param) { // 按照'&'分割每个参数
let [key, value] = param.split('='); // 按照'='分割每个参数中的键和值
extractParams[decodeURIComponent(key)] = decodeURIComponent(value); // 对键和值进行解码
});
console.log(extractParams); // { name: 'John', age: '30', city: 'New York' }
或者
let url = 'https://example.com/?name=John&age=30&city=New%20York';
let params = (new URL(url)).searchParams;
let extractParams = {};
for (let [key, value] of params) {
extractParams[key] = value;
}
console.log(extractParams); // { name: 'John', age: '30', city: 'New York' }
手写 Class 实现简易版发布订阅过程
class PubSub {
constructor() {
this.subscribers = {};
}
// 注册订阅者
subscribe(event, callback) {
if (!this.subscribers[event]) {
this.subscribers[event] = [];
}
this.subscribers[event].push(callback);
console.log(`订阅 ${event} 事件`);
}
// 注销订阅者
unsubscribe(event, callback) {
if (this.subscribers[event]) {
this.subscribers[event] = this.subscribers[event].filter(cb => cb !== callback);
}
console.log(`取消订阅 ${event} 事件`);
}
// 发布事件
publish(event, data) {
if (this.subscribers[event]) {
this.subscribers[event].forEach(callback => callback(data));
}
console.log(`发布 ${event} 事件,传递数据 ${data}`);
}
}
const pubsub = new PubSub();
// 注册订阅者
pubsub.subscribe('event1', () => console.log('收到 event1 事件'));
pubsub.subscribe('event2', (data) => console.log(`收到 event2 事件,传递数据 ${data}`));
// 发布事件
pubsub.publish('event1', 'Hello World!');
pubsub.publish('event2', 'Goodbye World!');
// 注销订阅者
pubsub.unsubscribe('event1', () => console.log('收到 event1 事件'));
实现一个函数 find(obj, str),满足:如var obj = {a:{b:{c:1}}};find(obj,'a.b.c') //返回1find(obj,'a.d.c') //返回undefined
第一版有问题只能是固定的输出结果
var obj = {
a:{
b:{
c:1
}
}
}
var str = 'a.b.c';
const find = (obj,str) => {
let arr = []
for (const key in str) {
if (Object.hasOwnProperty.call(str, key)) {
if (str[key]!= '.') {
arr.push(str[key])
}
}
}
try {
return `${obj[arr[0]][arr[1]][arr[2]]}`
} catch (error) {
return undefined
}
}
find(obj,'a.b.c')
find(obj,'a.d.c')
find(obj,null)
第二版升级版
function find(obj,str){
const arr=str?.split('.')||[]
let res=obj
for(let i=0;i<arr.length;i++){
res=res[arr[i]]
if (res===undefined) break;
}
return res
}
const objs={a:{b:{c:1}}}
console.log(find(objs,'a.b'))
如何提取高度嵌套的对象里的指定属性
要提取高度嵌套的对象中的指定属性,您可以使用递归来遍历对象并提取所需的属性。以下是一个示例函数,它接受两个参数:要提取的属性名称和要搜索的对象。
function extractNestedProperty(prop, obj) {
let result = obj;
// 递归遍历对象
for (let part of prop.split('.')) {
if (result[part] !== undefined) {
result = result[part];
} else {
return undefined;
}
}
return result;
}
const nestedObj = {
a: {
b: {
c: 123,
d: {
e: 456,
f: {
g: 789
}
}
},
h: {
i: {
j: 'abc'
}
}
}
};
console.log(extractNestedProperty('a.b.c', nestedObj)); // 输出:123
console.log(extractNestedProperty('a.b.d.e', nestedObj)); // 输出:456
console.log(extractNestedProperty('a.h.i.j', nestedObj)); // 输出:'abc'
console.log(extractNestedProperty('x.y', nestedObj)); // 输出:undefined
once
export function once (fn) {
// 利用闭包判断函数是否执行过
let called = false
return function () {
if (!called) {
called = true
fn.apply(this, arguments)
}
}
}
函数柯里化
console.log(curriedAdd(1)(2)(3)) // 输出 6
console.log(curriedAdd(1, 2)(3)) // 输出 6
console.log(curriedAdd(1)(2, 3)) // 输出 6
如何翻转一个字符串
function reverseString(str) {
return str.split('').reverse().join('');
}
let str = "Hello, World!";
console.log(reverseString(str)); // 输出: "!dlroW ,olleH"
找出任意html中的所有不重复的html的标签
// 获取文档中的所有标签
let tags = [...document.body.getElementsByTagName('*')].map(el => el.tagName);
// 移除重复的标签
let uniqueTags = [...new Set(tags)];
// 输出不重复的标签
console.log(uniqueTags);
手写实现数组map 和数组filter
map 原型链实现
Array.prototype._map=function(){
var newArr=[]
for(var i=0;i<this.length;i++){
newArr.push(fn(this[i],i))
}
return newArr
}
console.log(arr._map((v)=>v+1))
function map(array, callback) {
let result = [];
for(let i = 0; i < array.length; i++) {
result.push(callback(array[i], i, array));
}
return result;
}
// 使用示例:
let arr = [1, 2, 3, 4, 5];
let squared = map(arr, num => num * num);
console.log(squared); // 输出:[1, 4, 9, 16, 25]
filter
function filter(array, callback) {
let result = [];
for(let i = 0; i < array.length; i++) {
if(callback(array[i], i, array)) {
result.push(array[i]);
}
}
return result;
}
// 使用示例:
let arr = [1, 2, 3, 4, 5];
let even = filter(arr, num => num % 2 === 0);
console.log(even); // 输出:[2, 4]
Array.prototype._filter=function(){
var newArr=[]
for(var i=0;i<this.length;i++){
if(fn(this[i])){
newArr.push((this[i])
}
}
return newArr
}
console.log(arr._filter((v)=>v+1))
数组
给定一个整数数组,找到数组中的最大值并返回它的索引
function findMaxIndex(arr) {
let maxIndex = 0;
for (let i = 1; i < arr.length; i++) {
if (arr[i] > arr[maxIndex]) {
maxIndex = i;
}
}
return maxIndex;
}
findMaxIndex([1,2,3,55,7])
原型链上实现reduce
for
Array.prototype.myReduce = function (fn, initval) {
var arr = this;
if (typeof fn != "function") {
throw new TypeError("error");
}
//初始没值传入,使用数据第1个
if (typeof initval === "undefined") {
initval = arr[0];
for (var i = 1; i < arr.length; i++) {
initval = fn(initval, arr[i], i, arr);
}
} else {
//传入有值函数传入用初始值
for (var i = 0; i < arr.length; i++) {
initval = fn(initval, arr[i], i, arr);
}
}
return initval;
};
let arrs = [1, 2, 3];
let a = arrs.myReduce((initval, temp) => {
return initval + temp;
map
Array.prototype.myReduce = function (fn, initval) {
if (typeof fn !== "function") {
throw new TypeError("error");
}
let arr = this;
let accumulator = initval;
let currentValue = initval;
//判断默认值没有传值
if (typeof initval === "undefined") {
accumulator = arr[0];
currentValue = arr[1];
startIndex = 1;
} else {
if (arr.length === 0) {
return initval;
}
//判断传值了
accumulator = initval;
currentValue = arr[0];
startIndex = 0;
}
arr.map((item, index) => {
if (index < startIndex) {
return;
}
currentValue = item;
accumulator = fn(accumulator, currentValue, index, arr);
});
return accumulator;
};
let arrs = [1,2,3];
let a = arrs.myReduce((initval, temp) => {
return initval + temp;
},1);
console.log(a)
leetcode
现在面试要求特别高了,需要有算法能力,决定抽时间来刷lc
数组相关的
找出数组中出现次数1次的
一个由数字组成的数组,其中有一个数字出现1次,其它数字都出现了2次,编写方法 findSingleNumber,快速找出出现1次的数字。 测试用例: console.log(findSingleNumber([1, 0, 2, 4, 5, 2, 4, 1, 0])); // 输出:5
思路:利用对象来帮助,遍历的时候把每个数据做为对象的key来进行判断,如果出现过就把值设置2,没有出现过就设置成1
var singleNumber = function(nums) {
let obj={}
for(let i=0;i<nums.length;i++){
if(obj[nums[i]]){
obj[nums[i]]=2
}else{
obj[nums[i]]=1
}
}
for(key in obj){
if(obj[key]===1) return key
}
};
singleNumber([4,1,2,1,2])
也有可能同时出现多个1次的,那就可以放一个数组里接下来特殊需求的操作
两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入: nums = [2,7,11,15], target = 9
输出: [0,1]
解释: 因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入: nums = [3,2,4], target = 6
输出: [1,2]
这种题一般就是数组前一位和后一位相加来做对比,那这种就最简单的思路就是2层for循环
var twoSum = function(nums, target) {
let start=nums[0]
let res
for(let i=0;i<nums.length;i++){
for(let j=i+1;j<nums.length;j++){
if(Number(nums[i])+Number(nums[j])==target){
res=[i,j]
break;
}
}
}
return res
};
twoSum([2,7,11,15],9)
第二种解法
let nums=[11,2,7,15]
let target=9
function fn(nums,target){
let map=new Map()
nums.forEach((value,index)=>{
map.set(value,index)
})
//把map改造成{11 => 0, 2 => 1, 7 => 2, 15 => 3}
for(let i=0;i<nums.length;i++){
let j=map.get(target-nums[i]) //这里返回符合数据的下标
if(j!=undefined){
return [i,j]
}
}
return []
}
fn(nums,9)
第三种
let nums=[11,2,7,15]
let target=9
function fn(nums,target){
let arr=nums.map((value,index)=>{
return {value,index}
})
arr.sort((i,j)=>i.value-j.value)
console.log(arr)
let i=0,j=nums.length-1
while (i!=j) {
if(arr[i].value+arr[j].value===target){
return [arr[i].index,arr[j].index]
}else if(arr[i].value+arr[j].value>target){
j--
}else{
i++
}
}
}
fn(nums,9)
把字符串切成数组
'abcdefghi' 三三分组,结果:['abc', 'def', 'ghi']
var divideString = function (s, k) {
let result = []
for (let i = 0; i < s.length; i++) {
const str = s.slice(i * k, (i + 1) * k)
const l = str.length
if (l === k) {
result.push(str)
}
}
return result
}
divideString('abcdefghi',3)