Array.prototype.myForEach = function (callback,context=window) {
let self = this,
i = 0,
len = self.length;
len = self.length;
for (; i < len; i++) {
typeof callback == 'function' && callback.call(context,self[i], i)
}
}
Array.prototype.myFilter = function (callback, context = window) {
let len = this.length;
let newArr = [];
let i = 0;
for (; i < len; i++) {
if(callback.apply(context, [this[i], i , this])){
newArr.push(this[i]);
}
}
return newArr;
}
var users = [{
id: 1,
name: '张三'
},
{
id: 2,
name: '张三'
},
{
id: 3,
name: '张三'
},
{
id: 4,
name: '张三'
}
]
Array.prototype.myFind = function (callback) {
for (var i = 0; i < this.length; i++) {
if (callback(this[i], i)) {
return this[i]
}
}
}
var ret = users.myFind(function (item, index) {
return item.id === 2
})
console.log(ret)
Array.prototype.findIndex()
方法在数组中查找并返回第一个满足条件的元素的索引。如果没有找到这样的元素,则返回 -1。该方法接受一个回调函数作为参数,该回调函数接受三个参数:当前元素、当前索引和数组本身。回调函数必须返回一个布尔值,以指示当前元素是否满足条件
Array.prototype.myFindIndex = function (callback) {
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
return i;
}
}
return -1;
}
Array.prototype.map()
方法将原数组中的每个元素映射到一个新数组中,并返回新数组。它接受一个回调函数作为参数,该回调函数接受三个参数:当前元素、当前索引和数组本身。回调函数必须返回一个新的值,以指示当前元素在新数组中应该被映射成什么值。
Array.prototype.myMap = function (callback) {
const newArray = [];
for (let i = 0; i < this.length; i++) {
newArray.push(callback(this[i], i, this))
}
return newArray;
}
Array.prototype.reduce()
方法对数组中的所有元素执行一个 reducer 函数,并返回单个值。reducer 函数接收 4 个参数:累加器(accumulator)、当前值(currentValue)、当前索引(currentIndex)和数组(array)。累加器用于累计上一次调用 reducer 函数的结果,并将其返回作为下一次调用的累加器。
Array.prototype.myReduce = function (callback, initialValue) {
// 首先检查是否提供了初始值
let accumulator = initialValue !== undefined ? initialValue : this[0];
for (let i = initialValue !== undefined ? 0 : 1; i < this.length; i++) {
accumulator = callback(accumulator, this[i], i, this);
}
return accumulator;
}
every
方法用于判断数组中的所有元素是否都符合指定的条件。如果所有元素都符合条件,则返回true
,否则返回false
。
Array.prototype.myEvery = function (callback) {
for (let i = 0; i < this.length; i++) {
if (!callback(this[i], i, this)) {
return false;
}
}
return true;
}
some
方法用于判断数组中是否存在符合指定条件的元素。如果存在,则返回true
,否则返回false
。
Array.prototype.mySome = function (callback) {
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
return true;
}
}
return false;
};
flat
方法用于将多维数组扁平化为一维数组。如果需要扁平化的数组中存在多层嵌套的数组,flat
方法会递归地将其展开,直到所有元素都为基本类型为止。
Array.prototype.myFlat = function(depth = 1) {
if (depth === 0) {
return this;
}
return this.reduce((acc, cur) => {
if (Array.isArray(cur)) {
return acc.concat(cur.myFlat(depth - 1));
} else {
return acc.concat(cur);
}
}, []);
};
const arr = [1, [2, [3, 4], 5], 6];
console.log(arr.myFlat()); // [1, 2, [3, 4], 5, 6]
console.log(arr.myFlat(2)); // [1, 2, 3, 4, 5, 6]
let ary = [1, [2, [3, [4, 5]]], 6];
let str = JSON.stringify(ary);
ary = str.replace(/(\[|\])/g, '').split(',');
str = str.replace(/(\[\]))/g, '');
str = '[' + str + ']';
ary = JSON.parse(str);
let result = [];
let fn = function(ary) {
for(let i = 0; i < ary.length; i++) }{
let item = ary[i];
if (Array.isArray(ary[i])){
fn(item);
} else {
result.push(item);
}
}
}
Array.isArray()
方法用于确定传递的值是否是一个数组,它返回一个布尔值
function myIsArray(value) {
return Object.prototype.toString.call(value) === "[object Array]";
}
Array.of()
方法用于将一组值,转换为数组
Array()
的不足。因为参数个数的不同,会导致Array()
的行为有差异。Array.of()
基本上可以用来替代Array()
或new Array()
,并且不存在由于参数不同而导致的重载。它的行为非常统一function myArrayof() {
return Array.prototype.slice.call(arguments);
}
这个实现基于一个事实:当 slice()
方法的参数为空时,它会返回一个新数组,其中包含原数组的所有元素。
因此,我们可以使用该方法来实现 Array.of()
方法,只需要将 arguments
对象转换为数组,并返回该数组即可
function distinct(arr) {
for (let i = 0, len = arr.length; i < len; i++) {
for (let j = i + 1; j < len; j++) {
if (arr[i] == arr[j]) {
arr.splice(j, 1);
// splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一
len--;
j--;
}
}
}
return arr;
}
思想: 双重 for
循环是比较笨拙的方法,它实现的原理很简单:先定义一个包含原始数组第一个元素的数组,然后遍历原始数组,将原始数组中的每个元素与新数组中的每个元素进行比对,如果不重复则添加到新数组中,最后返回新数组;因为它的时间复杂度是O(n^2)
,如果数组长度很大,效率会很低
function distinct(a, b) {
let arr = a.concat(b);
return arr.filter((item, index)=> {
// 思想: 利用indexOf检测元素在数组中第一次出现的位置是否和元素现在的位置相等,如果不等则说明该元素是重复元素
return arr.indexOf(item) === index
})
}
思想: 利用
indexOf
检测元素在数组中第一次出现的位置是否和元素现在的位置相等,如果不等则说明该元素是重复元素
function distinct(array) {
return Array.from(new Set(array));
}
// 使用 Set 去重
function distinct(a, b) {
return [...new Set(a.concat(b))];
}
思想: ES6 提供了新的数据结构 Set,Set 结构的一个特性就是成员值都是唯一的,没有重复的值。
var resources = [{
name: "张三",
age: "18"
},
{
name: "张三",
age: "19"
},
{
name: "张三",
age: "20"
},
{
name: "李四",
age: "19"
},
{
name: "王五",
age: "20"
},
{
name: "赵六",
age: "21"
}
]
var temp = {};
resources = resources.reduce((prev, curv) => {
// 如果临时对象中有这个名字,什么都不做
if (temp[curv.name]) {
} else {
// 如果临时对象没有就把这个名字加进去,同时把当前的这个对象加入到prev中
temp[curv.name] = true;
prev.push(curv);
}
return prev
}, [])
console.log("结果", resources);
const responseList = [{
id: 1,
a: 1
},
{
id: 2,
a: 2
},
{
id: 3,
a: 3
},
{
id: 1,
a: 4
},
];
const result = responseList.reduce((acc, cur) => {
const ids = acc.map(item => item.id);
return ids.includes(cur.id) ? acc : [...acc, cur];
}, []);
console.log(result); // -> [ { id: 1, a: 1}, {id: 2, a: 2}, {id: 3, a: 3}
给定一个任意数组,实现一个通用函数,让数组中的数据根据 key 排重:
let data = [{
id: 1,
v: 1
},
{
id: 2,
v: 2
},
{
id: 1,
v: 1
},
];
const dedup = (data, getKey = () => {}) => {
const dateMap = data.reduce((pre, cur) => {
const key = getKey(cur);
if (!pre[key]) {
pre[key] = cur
}
return pre
}, {})
return Object.values(dateMap)
}
console.log(dedup(data, (item) => item.id))
// 以 id 作为排重 key,执行函数得到结果
// data = [
// { id: 1, v: 1 },
// { id: 2, v: 2 },
// ];
const arrayLike = document.querySelectorAll('div');
// 1.扩展运算符
[...arrayLike]
// 2.Array.from
Array.from(arrayLike)
// 3.Array.prototype.slice
Array.prototype.slice.call(arrayLike)
// 4.Array.apply
Array.apply(null, arrayLike)
// 5.Array.prototype.concat
Array.prototype.concat.apply([], arrayLike)
array.reduce(function(total, currentValue, currentIndex, arr), initialValue);
/*
total: 必需。初始值, 或者计算结束后的返回值。
currentValue: 必需。当前元素。
currentIndex: 可选。当前元素的索引;
arr: 可选。当前元素所属的数组对象。
initialValue: 可选。传递给函数的初始值,相当于total的初始值。
const arr = [12, 34, 23];
const sum = arr.reduce((total, num) => total + num);
// 设定初始值求和
const arr = [12, 34, 23];
const sum = arr.reduce((total, num) => total + num, 10); // 以10为初始值求和
// 对象数组求和
var result = [
{ subject: 'math', score: 88 },
{ subject: 'chinese', score: 95 },
{ subject: 'english', score: 80 }
];
const sum = result.reduce((accumulator, cur) => accumulator + cur.score, 0);
const sum = result.reduce((accumulator, cur) => accumulator + cur.score, -10); // 总分扣除10分
const a = [23,123,342,12];
const max = a.reduce((pre,next)=>pre>cur?pre:cur,0); // 342
var streams = [{name: '技术', id: 1}, {name: '设计', id: 2}];
var obj = streams.reduce((accumulator, cur) => {accumulator[cur.id] = cur; return accumulator;}, {});
var arr = [[1, 2, 8], [3, 4, 9], [5, 6, 10]];
var res = arr.reduce((x, y) => x.concat(y), []);
var newArr = arr.reduce(function (prev, cur) {
prev.indexOf(cur) === -1 && prev.push(cur);
return prev;
},[]);
const dedup = (data, getKey = () => { }) => {
const dateMap = data.reduce((pre, cur) => {
const key = getKey(cur)
if (!pre[key]) {
pre[key] = cur
}
return pre
}, {})
return Object.values(dateMap)
}
const str = 'sfhjasfjgfasjuwqrqadqeiqsajsdaiwqdaklldflas-cmxzmnha';
const res = str.split('').reduce((pre,next)=>{
pre[next] ? pre[next]++ : pre[next] = 1
return pre
},{})
function compose(...funs) {
if (funs.length === 0) {
return arg => arg;
}
if (funs.length === 1) {
return funs[0];
}
return funs.reduce((a, b) => (...arg) => a(b(...arg)))
}