数组reduce 5大应用场景你都知道吗?

272 阅读6分钟

大家好!今天我们将深入探讨JavaScript中的reduce方法,并通过五个实际应用场景,帮助大家更深刻地理解和体会reduce的便利性。

一、cookie工具函数的封装

在Web开发中,Cookie是一个常用的存储机制,用于在客户端保存用户信息。通过reduce方法,我们可以将Cookie字符串解析为一个对象,方便后续的操作。

const CookieUtil = {
  /**
   * 获取所有 Cookies,并将其转换为对象
   * 使用 reduce 解析 cookie 字符串
   */
  getCookies: function () {
    return document.cookie.split("; ").reduce((prev, cookieStr) => {
      const [key, value] = cookieStr.split("=");
      prev[decodeURIComponent(key)] = decodeURIComponent(value);
      return prev;
    }, {});
  },

  /**
   * 设置一个 Cookie
   * @param {string} name - Cookie 名称
   * @param {string} value - Cookie 值
   * @param {number} [days] - 过期天数
   * @param {string} [path] - Cookie 路径
   */
  setCookie: function (name, value, days, path = "/") {
    let cookieStr = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;

    if (days) {
      const expirationDate = new Date();
      expirationDate.setTime(
        expirationDate.getTime() + days * 24 * 60 * 60 * 1000
      );
      cookieStr += `; expires=${expirationDate.toUTCString()}`;
    }

    cookieStr += `; path=${path}`;
    document.cookie = cookieStr;
  },

  /**
   * 获取单个 Cookie 的值
   * @param {string} name - Cookie 名称
   * @returns {string | null} - Cookie 值或 null
   */
  getCookie: function (name) {
    const cookies = this.getCookies();
    return cookies[name] || null;
  },

  /**
   * 删除一个 Cookie
   * @param {string} name - Cookie 名称
   * @param {string} [path] - Cookie 路径
   */
  deleteCookie: function (name, path) {
    this.setCookie(name, "", -1, path);
  },
};

getCookies方法中,我们使用reduce将获取的Cookie转换为对象格式,从而可以通过键值对的方式获取具体Cookie的值。这种方式不仅提高了代码的可读性,也简化了Cookie的管理。

使用示例:

// 使用示例
CookieUtil.setCookie("userName", 7);
CookieUtil.getCookie("userName");

二、搜索功能

在处理数据时,模糊搜索是一个常见需求。通过reduce,我们可以实现对数组中对象(根据其中的某个字段)的模糊搜索,提高搜索效率。

比如有这样一组数据:

const mobileList = [
  { id: 1, name: "Mate XT 非凡大师" },
  { id: 2, name: "Mate 60 RS 非凡大师" },
  { id: 3, name: "Pura 70 Ultra" },
  { id: 4, name: "nova 13 Pro" },
  { id: 5, name: "nova Flip" },
];

现在对name 字段进行模糊搜索,就可以使用reduce



/**
 * 使用 reduce 实现模糊搜索
 * @param {Array} array - 要搜索的数组
 * @param {string} searchName - 搜索关键词
 * @returns {Array} - 匹配的手机类型数组
 */
const serchMobile = (array, searchName) => {
  const lowerCaseName = searchName.toLowerCase();
  return array.reduce((prev, mobile) => {
    if (mobile.name.toLowerCase().includes(lowerCaseName)) {
      prev.push(mobile);
    }
    return prev;
  }, []);
};

使用示例:


// 使用示例
const searchResult1 = searchName(mobileList, "mate");
console.log(searchResult1);

通过上面示例reduce的使用,我们可以轻松地实现对数组中元素的过滤操作,尤其是在需要对复杂数据结构进行筛选时,reduce的优势更加明显。

三、数据分类功能

数据分类是数据处理中的基础任务之一。通过reduce,我们可以根据指定的属性对数据进行分组,形成一个对象,键为分组依据,值为该组的数组。

有如下一段数据:

const products = [
  { id: 1, name: "苹果手机", category: "电子产品", price: 6999 },
  { id: 2, name: "耐克运动鞋", category: "服装", price: 1299 },
  { id: 3, name: "索尼耳机", category: "电子产品", price: 499 },
  { id: 4, name: "阿迪达斯T恤", category: "服装", price: 299 },
  { id: 5, name: "三星电视", category: "电子产品", price: 3999 },
  { id: 6, name: "优衣库牛仔裤", category: "服装", price: 599 },
  { id: 7, name: "戴尔笔记本", category: "电子产品", price: 5499 },
  { id: 8, name: "彪马跑步鞋", category: "服装", price: 899 },
  { id: 9, name: "LG空调", category: "家电", price: 2999 },
  { id: 10, name: "格力冰箱", category: "家电", price: 5999 },
];

现在想根据category 字段进行分组,就可以使用reduce 进行实现。

分组方法封装:

/**
 * 使用 reduce 方法按指定属性对数组进行分组
 * @param {Array} array - 要分组的数组
 * @param {String} key - 作为分组依据的属性
 * @returns {Object} - 分组后的对象
 */
const groupBy = (array, key) => {
  return array.reduce((prev, currentItem) => {
    // 获取当前项的分组键值
    const groupKey = currentItem[key];

    // 如果累加器中还未包含该键,则初始化为一个空数组
    if (!prev[groupKey]) {
      prev[groupKey] = [];
    }

    // 将当前项推入对应的分组数组中
    prev[groupKey].push(currentItem);

    return prev;
  }, {}); // 初始化累加器为一个空对象
};

使用示例:

// 使用示例
const groupedByCategory = groupBy(products, "category");

上面的示例可以看出这种分组操作在处理需要分类展示的数据时尤为实用,通过reduce,我们可以避免使用嵌套循环,提升代码的效率和简洁性。

四、计算总和

计算数组中数值项的总和是reduce的经典应用之一。通过定义一个初始值为0的累加器,我们可以轻松地实现这一功能。

还是用上面的数据,不过现在的需求是计算总价格了。

const products = [
  { id: 1, name: "苹果手机", category: "电子产品", price: 6999 },
  { id: 2, name: "耐克运动鞋", category: "服装", price: 1299 },
  { id: 3, name: "索尼耳机", category: "电子产品", price: 499 },
  { id: 4, name: "阿迪达斯T恤", category: "服装", price: 299 },
  { id: 5, name: "三星电视", category: "电子产品", price: 3999 },
  { id: 6, name: "优衣库牛仔裤", category: "服装", price: 599 },
  { id: 7, name: "戴尔笔记本", category: "电子产品", price: 5499 },
  { id: 8, name: "彪马跑步鞋", category: "服装", price: 899 },
  { id: 9, name: "LG空调", category: "家电", price: 2999 },
  { id: 10, name: "格力冰箱", category: "家电", price: 5999 },
];

计算总价格方法:

/**
 * 使用 reduce 方法计算商品价格的总和
 * @param {Array} productsArray - 商品数组
 * @returns {Number} - 所有商品价格的总和
 */
const calculateTotalPrice = (productsArray) => {
  return productsArray.reduce((total, product) => {
    return total + product.price;
  }, 0); // 初始值设为 0
};

使用示例:

const totalPrice = calculateTotalPrice(products);

这种方式不仅适用于价格计算,也可以用于任何需要累加的场景,如统计总分、计算总时长等。

五、统计数据出现的次数。

统计数据出现的次数可以帮助我们分析数据的分布情况。通过reduce,我们可以构建一个对象,记录每个元素出现的次数。

现在有这样一组订单数据:

const orderItems = [
  { id: 1, name: "苹果手机", category: "电子产品", price: 6999 },
  { id: 2, name: "耐克运动鞋", category: "服装", price: 1299 },
  { id: 1, name: "苹果手机", category: "电子产品", price: 6999 },
  { id: 3, name: "索尼耳机", category: "电子产品", price: 499 },
  { id: 2, name: "耐克运动鞋", category: "服装", price: 1299 },
  { id: 4, name: "阿迪达斯T恤", category: "服装", price: 299 },
  { id: 1, name: "苹果手机", category: "电子产品", price: 6999 },
  { id: 5, name: "三星电视", category: "电子产品", price: 3999 },
  { id: 3, name: "索尼耳机", category: "电子产品", price: 499 },
  { id: 6, name: "优衣库牛仔裤", category: "服装", price: 599 },
];

现在想统计每个商品有几个订单,就可以使用reduce 来计算。

方法封装:

/**
 * 使用 reduce 方法统计订单中相同商品的个数
 * @param {Array} items - 订单商品数组
 * @returns {Object} - 统计结果,键为商品ID,值为购买数量
 */
const countProducts = (items) => {
  return items.reduce((accumulator, currentItem) => {
    const productId = currentItem.id;
    const productName = currentItem.name;

    // 如果累加器中还未包含该商品ID,则初始化为对象 { name: 商品名称, count: 1 }
    if (!accumulator[productId]) {
      accumulator[productId] = { name: productName, count: 1 };
    } else {
      // 如果已经存在,则将计数器加1
      accumulator[productId].count += 1;
    }

    return accumulator;
  }, {}); // 初始化累加器为一个空对象
};

使用示例:

const productCounts = countProducts(orderItems);

上面的示例可以看出这种统计方式在需要对数据进行频率分析时非常有用,可以帮助我们快速识别出高频元素或异常数据。

通过以上五个应用场景,我们可以看到reduce方法在数据处理中的强大功能。它不仅简化了代码逻辑,也提升了代码的可读性和维护性。希望大家能够在实际项目中多加尝试,充分利用reduce的便利性。