likes
comments
collection
share

javaScript 实用算法(数组分组,数组去重,多条件查询,递归子树,新旧数组对象对比等)在前端开发中,算法不仅能提

作者站长头像
站长
· 阅读数 37

在前端开发中,算法不仅能提升代码性能和可维护性,还能帮助开发者高效地解决复杂问题。本文通过具体的 JavaScript 算法案例,详细讲解如何实现数组分组、找出数组对象中 id 的最大值和最小值、多条件模糊查询、数组对象去重、删除特定元素、数组对象排序、递归遍历树形结构、对象筛选以及对比并提取新旧数组对象中不同的元素等常见功能,并加上详细的注释帮助理解。


1. 数组分组(reduce)

描述

将数组按指定键进行分组,生成一个对象,每个键对应一个分组数组。

const products = [
  { id: 1, name: '苹果', category: '水果' },
  { id: 2, name: '香蕉', category: '水果' },
  { id: 3, name: '胡萝卜', category: '蔬菜' },
  { id: 4, name: '西兰花', category: '蔬菜' },
  { id: 5, name: '牛奶', category: '乳制品' }
];

function groupBy(array, key) {
  return array.reduce((result, current) => {
    const groupKey = current[key]; // 获取当前元素的分组键值
    if (!result[groupKey]) result[groupKey] = []; // 如果该键不存在,初始化为一个空数组
    result[groupKey].push(current); // 将当前元素添加到对应的分组数组中
    return result; // 返回更新后的分组结果
  }, {}); // 初始值为空对象
}

const groupedProducts = groupBy(products, 'category');
console.log(groupedProducts); // 打印分组后的结果
/* 输出: { 水果: [ { id: 1, name: '苹果', category: '水果' }, { id: 2, name: '香蕉', category: '水果' } ], 蔬菜: [ { id: 3, name: '胡萝卜', category: '蔬菜' }, { id: 4, name: '西兰花', category: '蔬菜' } ], 乳制品: [ { id: 5, name: '牛奶', category: '乳制品' } ] } */

注释说明

  • groupBy 函数:使用 reduce 方法遍历数组,根据传入的 key 对元素进行分组,最终返回一个包含多个组的对象。
  • result[groupKey] :每次遍历时,检查分组键是否已存在,如果不存在则初始化为空数组,之后将当前项加入对应组。

2. 数组对象去重

描述

从数组中根据id移除重复对象,保留唯一对象。

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 1, name: 'Alice' },
  { id: 3, name: 'Charlie' },
  { id: 2, name: 'Bob' }
];

function removeDuplicates(array, key) {
  const seen = new Set(); // 使用 Set 记录已出现的键值
  return array.filter(item => {
    const val = item[key]; // 获取当前元素的键值
    if (seen.has(val)) return false; // 如果键值已存在,则跳过此元素
    seen.add(val); // 否则,将键值添加到 Set 中,并保留此元素
    return true;
  });
}

const uniqueUsers = removeDuplicates(users, 'id');
console.log(uniqueUsers); // 打印去重后的数组

注释说明

  • 去重逻辑:使用 Set 来存储已经见过的 id 值,只有首次出现的元素会被保留,重复的则会被过滤掉。

3. 找出数组对象中 id 最大值和最小值

描述

通过对数组对象按 id 排序,找出 id 的最小值和最大值。

const users = [
  { id: 3, name: 'Charlie' },
  { id: 1, name: 'Alice' },
  { id: 4, name: 'Dave' },
  { id: 2, name: 'Bob' }
];
const sortedUsers = [...users].sort((a, b) => a.id - b.id); // 按 id 升序排序
const minUser = sortedUsers[0]; // 数组第一个元素即为最小 id 的对象
const maxUser = sortedUsers[sortedUsers.length - 1]; // 数组最后一个元素为最大 id 的对象

console.log('最小ID:', minUser); // 输出: { id: 1, name: 'Alice' }
console.log('最大ID:', maxUser); // 输出: { id: 4, name: 'Dave' }

注释说明

  • sort 方法:通过 sort 方法对数组进行升序排序,a.id - b.id 表示按 id 大小排序。
  • minUser 和 maxUser:排序后,第一个元素为最小 id,最后一个元素为最大 id

4. 多条件模糊查询

描述

根据多个条件进行模糊查询,忽略字符串大小写,支持部分匹配。

const users = [
  { id: 1, name: 'Alice', role: 'Admin' },
  { id: 2, name: 'bob', role: 'User' },
  { id: 3, name: 'Charlie', role: 'admin' },
  { id: 4, name: 'dave', role: 'User' },
  { id: 5, name: 'Eve', role: 'Guest' }
];

function multiConditionFuzzyFilter(array, conditions) {
  return array.filter(item =>
    // 遍历每个查询条件,检查是否满足
    Object.keys(conditions).every(key => {
      const itemValue = item[key]?.toString().toLowerCase(); // 将当前对象的属性值转换为小写
      const conditionValue = conditions[key]?.toString().toLowerCase(); // 将查询条件值转换为小写
      return itemValue.includes(conditionValue); // 检查属性值是否包含查询条件值
    })
  );
}

// 模糊查询 role 包含 'admin' 且 name 包含 'a'
const filteredUsers = multiConditionFuzzyFilter(users, { role: 'admin', name: 'a' });
console.log(filteredUsers); // 打印符合条件的对象数组
/* 输出: [ { id: 1, name: 'Alice', role: 'Admin' }, { id: 3, name: 'Charlie', role: 'admin' } ] */

注释说明

  • 模糊匹配includes 用于检查字符串是否包含指定值,支持部分匹配。
  • 忽略大小写:将字符串转为小写,以确保查询结果不受大小写影响。

5. 去除数组对象中 id 为 2 的元素

描述

从数组中删除 id 为特定值的对象。

示例代码

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' },
  { id: 2, name: 'Bob' },
  { id: 4, name: 'Dave' }
];

function removeById(array, idToRemove) {
  return array.filter(item => item.id !== idToRemove); // 过滤出不等于指定 id 的元素
}

const updatedUsers = removeById(users, 2);
console.log(updatedUsers); // 打印移除后的数组

注释说明

  • 过滤逻辑:通过 filter 过滤掉 id 等于 idToRemove 的对象,保留其他元素。

6. 使用递归遍历树形结构

描述

递归遍历树形结构的数据,如组织结构图、文件目录等,执行操作。

const treeData = [  {    id: 1,    name: '根节点',    children: [      {        id: 2,        name: '子节点1',        children: [          { id: 4, name: '子节点1-1', children: [] },
          { id: 5, name: '子节点1-2', children: [] }
        ]
      },
      { id: 3, name: '子节点2', children: [] }
    ]
  }
];

function traverseTree(nodes, callback) {
  nodes.forEach(node => {
    callback(node); // 对当前节点执行操作
    if (node.children && node.children.length > 0) {
      traverseTree(node.children, callback); // 如果有子节点,则递归遍历子节点
    }
  });
}

// 示例:打印所有节点的名称
traverseTree(treeData, node => console.log(node.name));

注释说明

  • 递归逻辑:遍历每个节点并递归处理其子节点,使用回调函数对每个节点执行特定操作。

7. 对比新旧数组对象并提取不同元素

描述

通过对比两个数组对象,先使用 JSON.stringify 对比两个数组是否相同,再逐项对比每个子项并提取不同的元素。

const oldUsers = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
];

const newUsers = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bobby' }, // 名字变更
  { id: 4, name: 'Dave' }
];

function arraysEqual(arr1, arr2) {
  return JSON.stringify(arr1) === JSON.stringify(arr2); // 通过将数组对象序列化为字符串来比较
}

function findDifferences(arr1, arr2) {
  const differences = [];

  arr2.forEach(newItem => {
    const oldItem = arr1.find(item => item.id === newItem.id); // 查找新数组中的元素是否在旧数组中
    if (!oldItem || JSON.stringify(newItem) !== JSON.stringify(oldItem)) {
      differences.push(newItem); // 如果新旧元素不同,或者新元素不存在于旧数组中,则将其加入差异数组
    }
  });

  return differences; // 返回不同的元素数组
}

const areArraysEqual = arraysEqual(oldUsers, newUsers); // 判断两个数组是否相同
console.log('数组是否相同:', areArraysEqual);

const differentUsers = findDifferences(oldUsers, newUsers); // 找出不同的元素
console.log('不同的元素:', differentUsers);

注释说明

  • arraysEqual 函数:使用 JSON.stringify 序列化数组对象进行整体对比,判断两个数组是否完全相同。
  • findDifferences 函数:遍历新数组,逐项与旧数组进行对比,找出不同的元素并返回。

总结

通过多个实用的 JavaScript 算法案例,本文展示了如何处理数组和对象的常见问题,并结合详细注释帮助理解代码逻辑。掌握这些算法,不仅能够提高开发效率,还能帮助开发者轻松应对复杂的数据处理场景。

希望这些案例对您有所帮助,欢迎在项目中灵活运用!

转载自:https://juejin.cn/post/7415654362992689167
评论
请登录