JavaScript棘手代码第二部分
JavaScript代码系列(5部分)
JavaScript棘手代码第一部分
在JavaScript中处理设备方向
JavaScript棘手代码第二部分
JavaScript棘手代码第三部分
数组变异和非变异方法
问题1:在嵌套对象中查找并打印年龄大于30的用户姓名
JavaScript文件:
- const users = {
- user1: {
- name: "Alice",
- age: 25,
- details: {
- city: "New York",
- occupation: "Engineer"
- }
- },
- user2: {
- name: "Bob",
- age: 35,
- details: {
- city: "Los Angeles",
- occupation: "Designer"
- }
- },
- user3: {
- name: "Charlie",
- age: 28,
- details: {
- city: "Chicago",
- occupation: "Manager"
- }
- },
- user4: {
- name: "David",
- age: 42,
- details: {
- city: "Houston",
- occupation: "Developer"
- }
- }
- };
- // 解决方案
- function findUsersOver30(obj) {
- const result = [];
- for (const key in obj) {
- if (obj[key].age > 30) {
- result.push(obj[key].name);
- }
- }
- return result;
- }
- const usersOver30 = findUsersOver30(users);
- console.log(usersOver30); // 输出: ["Bob", "David"]
输出: ["Bob", "David"]
解释:
这个解决方案遍历嵌套对象,检查每个用户的年龄是否大于30,如果满足条件就将用户名添加到结果数组中。
问题2:扁平化数组 (输入: [1,2,[3,4], 5], 输出: [1,2,3,4,5])
解决方案1:使用flat()方法
- const arr = [1, 2, [3, 4], 5];
- const flattenedArr = arr.flat();
- console.log(flattenedArr); // 输出: [1, 2, 3, 4, 5]
但是这种方法不会扁平化多层嵌套。
解决方案2:使用flat()配合Infinity
- const arr = [1, 2, [3, 4, [5, 6]], 7];
- const flattenedArr = arr.flat(Infinity);
- console.log(flattenedArr); // 输出: [1, 2, 3, 4, 5, 6, 7]
解决方案3:使用递归和for循环
- function flattenArray(arr) {
- let result = [];
- arr.forEach(item => {
- if (Array.isArray(item)) {
- result = result.concat(flattenArray(item));
- // ---------- 或者 ------
- // result = [...result, ...flattenArray(item)];
- } else {
- result.push(item);
- }
- });
- return result;
- }
- const arr = [1, 2, [3, 4, [5, 6]], 7];
- const flattenedArr = flattenArray(arr);
- console.log(flattenedArr); // 输出: [1, 2, 3, 4, 5, 6, 7]
解决方案4:使用递归和reduce方法
- function flattenArray(arr) {
- return arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flattenArray(val) : val), []);
- }
- const arr = [1, 2, [3, 4, [5, 6]], 7];
- const flattenedArr = flattenArray(arr);
- console.log(flattenedArr); // 输出: [1, 2, 3, 4, 5, 6, 7]
解决方案对比分析
flat()方法
优点:简洁、内置方法
缺点:需要指定深度,多层嵌套需要Infinity
适用场景:简单的一层或已知深度的扁平化
递归方法
优点:可以处理任意深度的嵌套
缺点:代码相对复杂
适用场景:未知深度的复杂嵌套数组
reduce方法
优点:函数式编程风格,代码简洁
缺点:可能不如for循环直观
适用场景:偏好函数式编程的场景
性能考虑
flat()方法:现代浏览器中性能最好
递归方法:对于深层嵌套可能产生栈溢出
迭代方法:可以避免栈溢出,适合大数据集
实际应用场景
数据处理:处理来自API的嵌套数据
表单数据:扁平化表单字段
配置对象:处理嵌套的配置结构
树形结构:将树形数据转换为扁平列表
📌📌 更多JavaScript棘手问题请访问:
关键概念总结
对象遍历:使用for...in循环遍历对象属性
数组扁平化:多种方法处理嵌套数组
递归编程:处理未知深度的数据结构
函数式编程:使用reduce等函数式方法
性能优化:选择合适的方法处理不同场景
扩展练习
练习1:深度扁平化对象
- const deepObject = {
- a: 1,
- b: {
- c: 2,
- d: {
- e: 3,
- f: [4, 5, { g: 6 }]
- }
- }
- };
- // 将嵌套对象扁平化为单层对象
- function flattenObject(obj, prefix = '') {
- return Object.keys(obj).reduce((acc, key) => {
- const pre = prefix.length ? prefix + '.' : '';
- if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
- Object.assign(acc, flattenObject(obj[key], pre + key));
- } else {
- acc[pre + key] = obj[key];
- }
- return acc;
- }, {});
- }
- console.log(flattenObject(deepObject));
- // 输出: { a: 1, 'b.c': 2, 'b.d.e': 3, 'b.d.f': [4, 5, { g: 6 }] }
练习2:条件扁平化
- function conditionalFlatten(arr, condition) {
- return arr.reduce((acc, item) => {
- if (Array.isArray(item) && condition(item)) {
- return acc.concat(conditionalFlatten(item, condition));
- } else if (Array.isArray(item)) {
- return acc.concat(item);
- } else {
- return acc.concat(item);
- }
- }, []);
- }
- // 只扁平化包含数字的数组
- const mixedArray = [1, [2, 3], ['a', 'b'], [4, [5, 6]]];
- const result = conditionalFlatten(mixedArray, arr =>
- arr.some(item => typeof item === 'number')
- );
- console.log(result);
