是什么
开发中处理数组对象,会遇到一些问题。
以下做个笔记
- 问题一:数组去重复
- 问题二:数组对象去重复
- 问题三:数组替换值
- 问题四:数组合并
- 问题五:数组删除虚值
- 问题六:数组取随机值
- 问题七:数组求和
- 问题八:数组反转
- 问题九:数组转对象
- 问题十:数组对象取指定键值
- 问题十一:数组转字符串
- 问题十二:数组合并
- 问题十三:数组交集
- 问题十四:数组差集
- 问题十五:数组遍历
- 问题十六:判断数组中是否有符合条件的值
- 问题十七:判断数组中所有元素是否都符合条件
- 问题十八:找到第一个符合条件的元素/下标
- 问题十九:数组浅复制/深复制
- 问题二十:数组最大最小值
- 问题二十一:数组元素个数统计
- 问题二十二:数组元素位置统计
- 问题二十三:数组按元素分组
- 问题二十四:数组url 参数序列化
- 问题二十五:数组url 参数反序列化
- 问题二十六:数组扁平
- 问题二十七:数组 reduce 函数
- 问题二十八:数组对象获取下标
- 问题二十九:数组递归树形
- 问题三十:数组 reduce 生成html
返回新数组,不改变原数组: join concat slice map every some filter forEach reduce
返回新数组,改变原数组:push pop shift unshift reverse sort slice
问题一:数组去重复
const unique = arr => arr.filter((element, index, self) => self.indexOf(element) === index);
问题二:数组对象去重复
const arr = [
{ id: 1, name: '张三' },
{ id: 2, name: '李四' },
{ id: 11, name: '王五' },
{ id: 1, name: '张三' },
{ id: 11, name: '王五' },
{ id: 3, name: '李四' }
];
const unique = (arr, name) => {
let cache = [];
for(let item of arr){
if(cache.find(v => v[name] === item[name])) {
continue;
}
cache.push(item);
}
return cache;
}
const filterNonUniqueBy = (arr, fn) =>
arr.filter((val, index) =>
arr.every((x, y) => (index === y) === fn(val, x, index, y))
);
// filterNonUniqueBy(arr,(a, b) => a.id === b.id)
console.log(unique(arr, 'id'));
// [{id: 1, name: "张三"}, {id: 2, name: "李四"}, {id: 11, name: "王五"}, {id: 3, name: "李四"}]
问题三:数组替换值
var cache = ['wxh','wxh2','wxh3','wxh4','wxh5']
cache.splice(0,2,'wxh','wxh')
console.log(cache) // ['wxh','wxh','wxh3','wxh4','wxh5']
问题四:数组合并
var array = [1,2,2,3,5,6];
var array2 = [1,2,2,3,5,6];
var cache = [...array,...array2]
问题五:数组删除虚值
var array = [1,2,2,3,5,6];
// 在 JS 中,虚值有 false, 0,'', null, NaN, undefined。咱们可以 .filter() 方法来过滤这些虚值。
var cache = array.filter(Boolean);
问题六:数组取随机值
var array = [1,2,2,3,5,6];
var cache = array[(Math.floor(Math.random() * (array.length)))];
问题七:数组求和
var array = [1,2,2,3,5,6];
var cache = array.reduce((x,y) => x + y);
问题八:数组反转
function Reverse(arr) {
return arr.reduceRight((item,value) => (item.push(value),item),[]);
}
//[5, 4, 3, 2, 1]
问题九:数组转对象
const cache = [1, 2, 3, 4];
const arrayToObject = {...arr}; // {0: 1, 1: 2, 2: 3, 3: 4}
const cache = {'name':'wxh', 'title':'hello world'}
const ObjectToArray = Object.getOwnPropertyNames(cache); // ["name", "title"]
const ObjectToArray = Object.keys(cache).map(function(i){return cache[i]}); // ["wxh", "hello world"]
问题十:数组对象取指定键值
function GetKeys(obj = {}, keys = []) {
return Object.keys(obj).reduce((t, v) => (keys.includes(v) && (t[v] = obj[v]), t), {});
}
const cache = { a: 1, b: 2, c: 3, d: 4 };
const keyword = ["a", "d"];
GetKeys(cache, keyword); // { a: 1, d: 4 }
问题十一:数组转字符串
const cache = [1, 2, 3, 4];
const str = cache.join(","); // 数组转字符串
const arr = str.split(","); // 字符串转数组
问题十二:数组合并
const cache = [1, 2, 3, 4];
const arr = [...cache, ...cache, ...cache]
问题十三:数组交集
const cache = [0, 1, 2, 3, 4, 5]
const b = [3, 4, 5, 6, 7, 8]
const joinValue = [...new Set(cache)].filter(item => b.includes(item)) // [3, 4, 5]
let cache = [{a:'1',b:'12'}, {a:'0', b:'12'}]
let cache1 = [{a:'2',b:'23'}, {a:'0', b:'12'}]
let cache2 = cache.map(item=>item.a)
let cache3 = cache1.filter(info=>{
return new Set(cache2).has(info.a)
})
console.log(cache3) // [{a:'0', b:'12'}]
- 问题十四:数组差集
const a = [0, 1, 2, 3, 4, 5]
const b = [3, 4, 5, 6, 7, 8]
const diffValues = [...new Set([...a, ...b])].filter(item => !b.includes(item) || !a.includes(item))
// [0, 1, 2, 6, 7, 8]
- 问题十五:数组遍历
// 数组遍历
const cache = [0, 1, 2, 3, 4, 5]
console.log(cache.map(i => i));
const copy = [];
cache.forEach(function(val, index) {
copy.push(val);
})
for (var i in cache){
console.log(i,":",cache[i]);
}
// 对象遍历
const cache = [{a:'1',b:'12'}, {a:'0', b:'12'}];
Object.keys(cache).forEach(function(key){
console.log(key,cache[key]);
});
Object.getOwnPropertyNames(cache).forEach(function(key){
console.log(key,cache[key]);
});
for(var i of cache) {
console.log(i,":",cache[i]);
}
// 含Symbol属性
Reflect.ownKeys(cache).forEach(function(key){
console.log(key,cache[key]);
});
问题十六:判断数组中是否有符合条件的值
// 数组
const cache = [1, 2, 3, 4, 5]
const hasNum = cache.some(item => typeof item === 'number')
// 对象
const reducedFilter = (data, keys, fn) =>
data.filter(fn).map((el) =>
keys.reduce((acc, key) => {
acc[key] = el[key];
return acc;
}, {})
);
const dataFilter = [
{
id: 1,
name: "john",
age: 24,
},
{
id: 2,
name: "mike",
age: 50,
},
];
console.log(
"按照条件筛选数据对象",
reducedFilter(dataFilter, ["id", "name"], (item) => item.age > 24)
);
问题十七:判断数组中所有元素是否都符合条件
const cache = [1, 2, 3, 4, 5]
const isAllNum = cache.every(item => typeof item === 'number')
问题十八:找到第一个符合条件的元素/下标
const cache = [1, 2, 3, 4, 5]
const findItem = cache.find(item => item === 3) // 返回子项
const findIndex = cache.findIndex(item => item === 3) // 返回子项的下标
问题十九:数组浅复制/深复制
const cache = [1, 2, 3]
const arrClone = [...cache]
const arrClone = Array.from(cache);
const arrClone = cache.slice(0, cache.length)
const cache = { a: 1 }
const objClone = { ...cache }
function deepClone(object) {
var clone = {};
for (var key in object) {
var value = object[key];
if (typeof(value) !== 'object') {
clone[key] = value;
} else {
clone[key]=deepClone(value);
}
}
return clone;
}
const objClone = deepClone(cache)
问题二十:数组最大最小值
function Max(arr = []) {
return arr.reduce((t, v) => t > v ? t : v);
}
function Min(arr = []) {
return arr.reduce((t, v) => t < v ? t : v);
}
问题二十一:数组元素个数统计
function Count(arr = []) {
return arr.reduce((t, v) => (t[v] = (t[v] || 0) + 1, t), {});
}
const cache = [0, 1, 1, 2, 2, 2];
Count(cache); // { 0: 1, 1: 2, 2: 3 }
问题二十二:数组元素位置统计
function Count(arr = [], val) {
return arr.reduce((t, v, i) => (v === val && t.push(i), t), []);
}
const cache = [2, 1, 5, 4, 2, 1, 6, 6, 7];
Count(cache, 2); // [0, 4]
问题二十三:数组按元素分组
function Group(arr = [], key) {
return key ? arr.reduce((t, v) => (!t[v[key]] && (t[v[key]] = []), t[v[key]].push(v), t), {}) : {};
}
const cache = [
{ city: "GZ", name: "YZW", age: 127 },
{ city: "GZ", name: "TYJ", age: 125 },
{ city: "SZ", name: "AAA", age: 123 },
{ city: "FS", name: "BBB", age: 121 },
{ city: "SZ", name: "CCC", age: 119 }
];
// 以city作为分组依据
Group(cache, "city"); // { GZ: Array(2), SZ: Array(2), FS: Array(1) }
问题二十四:数组url 参数序列化
function paramsUrl(search = {}) {
return Object.entries(search).reduce(
(t, v) => `${t}${v[0]}=${encodeURIComponent(v[1])}&`,
Object.keys(search).length ? "?" : ""
).replace(/&$/, "");
}
paramsUrl({ age: 27, name: "test" }); // "?age=27&name=test"
问题二十五:数组url 参数反序列化
function ParseUrlSearch() {
return location.search.replace(/(^\?)|(&$)/g, "").split("&").reduce((t, v) => {
const [key, val] = v.split("=");
t[key] = decodeURIComponent(val);
return t;
}, {});
}
// https://www.baidu.com?age=27&name=test
ParseUrlSearch() // { age: "27", name: "test" }
问题二十六:数组扁平
function Flat(arr = []) {
return arr.reduce((t, v) => t.concat(Array.isArray(v) ? Flat(v) : v), [])
}
const cache = [0, 1, [2, 3], [4, 5, [6, 7]], [8, [9, 10, [11, 12]]]];
Flat(cache); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
问题二十七:数组 reduce 函数
const cache = [0, 1, 2, 3];
// 代替map:[0, 2, 4, 6]
const a = cache.map(v => v * 2);
const b = cache.reduce((t, v) => [...t, v * 2], []);
// 代替filter:[2, 3]
const c = cache.filter(v => v > 1);
const d = cache.reduce((t, v) => v > 1 ? [...t, v] : t, []);
// 代替map和filter:[4, 6]
const e = cache.map(v => v * 2).filter(v => v > 2);
const f = cache.reduce((t, v) => v * 2 > 2 ? [...t, v * 2] : t, []);
const cache = [
{ score: 45, subject: "chinese" },
{ score: 90, subject: "math" },
{ score: 60, subject: "english" }
];
// 代替some:至少一门合格
const isAtLeastOneQualified = cache.reduce((t, v) => t || v.score >= 60, false); // true
// 代替every:全部合格
const isAllQualified = cache.reduce((t, v) => t && v.score >= 60, true); // false
问题二十八:数组对象获取下标
const sortedIndexBy = (arr, n, fn) => {
const isDescending = fn(arr[0]) > fn(arr[arr.length - 1]);
const val = fn(n);
const index = arr.findIndex((el) =>
isDescending ? val >= fn(el) : val <= fn(el)
);
return index === -1 ? arr.length : index;
};
console.log(
"获取下标",
sortedIndexBy([{ x: 14 }, { x: 35 }], { x: 35 }, (o) => o.x) // 1
);
问题二十九:数组递归树形
const nest = (items, id = null, link = "parent_id") =>
items
.filter((item) => item[link] === id)
.map((item) => ({ ...item, children: nest(items, item.id, link) }));
const comments = [
{ id: 1, parent_id: null },
{ id: 2, parent_id: 1 },
{ id: 3, parent_id: 1 },
{ id: 4, parent_id: 2 },
{ id: 5, parent_id: 4 },
];
const nestedComments = nest(comments);
console.log("递归树形", nestedComments);
问题三十:数组 reduce 生成html
// 后端返回数据
const datas = {
'name': [
'wxh',
'wxh',
'wxh',
],
'age': [
'wxh',
'wxh',
'wxh',
]
}
const _data = Object.entries(datas).reduce((prev, cur) => {
const values = cur[1].reduce((prev, cur) => `${prev}<p>${cur}</p>`, '')
return `${prev}
<li>
<p>${cur[0]}</p>
${values}
</li>`
}, '')
const html = `
<ul class="nlp-notify-body">
${_data}
</ul>
`
console.log(html);