JavaScript棘手代码第二部分

JavaScript代码系列(5部分)
JavaScript棘手代码第一部分
在JavaScript中处理设备方向
JavaScript棘手代码第二部分
JavaScript棘手代码第三部分
数组变异和非变异方法
问题1:在嵌套对象中查找并打印年龄大于30的用户姓名
JavaScript文件:
  1. const users = {
  2. user1: {
  3. name: "Alice",
  4. age: 25,
  5. details: {
  6. city: "New York",
  7. occupation: "Engineer"
  8. }
  9. },
  10. user2: {
  11. name: "Bob",
  12. age: 35,
  13. details: {
  14. city: "Los Angeles",
  15. occupation: "Designer"
  16. }
  17. },
  18. user3: {
  19. name: "Charlie",
  20. age: 28,
  21. details: {
  22. city: "Chicago",
  23. occupation: "Manager"
  24. }
  25. },
  26. user4: {
  27. name: "David",
  28. age: 42,
  29. details: {
  30. city: "Houston",
  31. occupation: "Developer"
  32. }
  33. }
  34. };

  35. // 解决方案
  36. function findUsersOver30(obj) {
  37. const result = [];
  38. for (const key in obj) {
  39. if (obj[key].age > 30) {
  40. result.push(obj[key].name);
  41. }
  42. }
  43. return result;
  44. }

  45. const usersOver30 = findUsersOver30(users);
  46. console.log(usersOver30); // 输出: ["Bob", "David"]
javascript
输出: ["Bob", "David"]
解释:
这个解决方案遍历嵌套对象,检查每个用户的年龄是否大于30,如果满足条件就将用户名添加到结果数组中。
问题2:扁平化数组 (输入: [1,2,[3,4], 5], 输出: [1,2,3,4,5])
解决方案1:使用flat()方法
  1. const arr = [1, 2, [3, 4], 5];
  2. const flattenedArr = arr.flat();
  3. console.log(flattenedArr); // 输出: [1, 2, 3, 4, 5]
javascript
但是这种方法不会扁平化多层嵌套
解决方案2:使用flat()配合Infinity
  1. const arr = [1, 2, [3, 4, [5, 6]], 7];
  2. const flattenedArr = arr.flat(Infinity);
  3. console.log(flattenedArr); // 输出: [1, 2, 3, 4, 5, 6, 7]
javascript
解决方案3:使用递归和for循环
  1. function flattenArray(arr) {
  2. let result = [];
  3. arr.forEach(item => {
  4. if (Array.isArray(item)) {
  5. result = result.concat(flattenArray(item));
  6. // ---------- 或者 ------
  7. // result = [...result, ...flattenArray(item)];
  8. } else {
  9. result.push(item);
  10. }
  11. });
  12. return result;
  13. }

  14. const arr = [1, 2, [3, 4, [5, 6]], 7];
  15. const flattenedArr = flattenArray(arr);
  16. console.log(flattenedArr); // 输出: [1, 2, 3, 4, 5, 6, 7]
javascript
解决方案4:使用递归和reduce方法
  1. function flattenArray(arr) {
  2. return arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flattenArray(val) : val), []);
  3. }

  4. const arr = [1, 2, [3, 4, [5, 6]], 7];
  5. const flattenedArr = flattenArray(arr);
  6. console.log(flattenedArr); // 输出: [1, 2, 3, 4, 5, 6, 7]
javascript
解决方案对比分析
flat()方法
优点:简洁、内置方法
缺点:需要指定深度,多层嵌套需要Infinity
适用场景:简单的一层或已知深度的扁平化
递归方法
优点:可以处理任意深度的嵌套
缺点:代码相对复杂
适用场景:未知深度的复杂嵌套数组
reduce方法
优点:函数式编程风格,代码简洁
缺点:可能不如for循环直观
适用场景:偏好函数式编程的场景
性能考虑
flat()方法:现代浏览器中性能最好
递归方法:对于深层嵌套可能产生栈溢出
迭代方法:可以避免栈溢出,适合大数据集
实际应用场景
数据处理:处理来自API的嵌套数据
表单数据:扁平化表单字段
配置对象:处理嵌套的配置结构
树形结构:将树形数据转换为扁平列表
📌📌 更多JavaScript棘手问题请访问:
关键概念总结
对象遍历:使用for...in循环遍历对象属性
数组扁平化:多种方法处理嵌套数组
递归编程:处理未知深度的数据结构
函数式编程:使用reduce等函数式方法
性能优化:选择合适的方法处理不同场景
扩展练习
练习1:深度扁平化对象
  1. const deepObject = {
  2. a: 1,
  3. b: {
  4. c: 2,
  5. d: {
  6. e: 3,
  7. f: [4, 5, { g: 6 }]
  8. }
  9. }
  10. };

  11. // 将嵌套对象扁平化为单层对象
  12. function flattenObject(obj, prefix = '') {
  13. return Object.keys(obj).reduce((acc, key) => {
  14. const pre = prefix.length ? prefix + '.' : '';
  15. if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
  16. Object.assign(acc, flattenObject(obj[key], pre + key));
  17. } else {
  18. acc[pre + key] = obj[key];
  19. }
  20. return acc;
  21. }, {});
  22. }

  23. console.log(flattenObject(deepObject));
  24. // 输出: { a: 1, 'b.c': 2, 'b.d.e': 3, 'b.d.f': [4, 5, { g: 6 }] }
javascript
练习2:条件扁平化
  1. function conditionalFlatten(arr, condition) {
  2. return arr.reduce((acc, item) => {
  3. if (Array.isArray(item) && condition(item)) {
  4. return acc.concat(conditionalFlatten(item, condition));
  5. } else if (Array.isArray(item)) {
  6. return acc.concat(item);
  7. } else {
  8. return acc.concat(item);
  9. }
  10. }, []);
  11. }

  12. // 只扁平化包含数字的数组
  13. const mixedArray = [1, [2, 3], ['a', 'b'], [4, [5, 6]]];
  14. const result = conditionalFlatten(mixedArray, arr =>
  15. arr.some(item => typeof item === 'number')
  16. );
  17. console.log(result);
javascript