数据统计

JavaScript 中常见的数据统计方法实现

问题

实现常见的数据统计功能,包括元素计数、求和、平均值、分组统计等。

解答

统计元素出现次数

// 统计数组中每个元素出现的次数
function countElements(arr) {
  return arr.reduce((acc, item) => {
    acc[item] = (acc[item] || 0) + 1;
    return acc;
  }, {});
}

// 示例
const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
console.log(countElements(fruits));
// { apple: 3, banana: 2, orange: 1 }

统计字符出现次数

// 统计字符串中每个字符出现的次数
function countChars(str) {
  const result = {};
  for (const char of str) {
    result[char] = (result[char] || 0) + 1;
  }
  return result;
}

// 示例
console.log(countChars('hello'));
// { h: 1, e: 1, l: 2, o: 1 }

基本统计量

// 计算数组的基本统计量
function getStats(arr) {
  if (arr.length === 0) return null;

  const sum = arr.reduce((a, b) => a + b, 0);
  const avg = sum / arr.length;
  const max = Math.max(...arr);
  const min = Math.min(...arr);

  // 排序后取中位数
  const sorted = [...arr].sort((a, b) => a - b);
  const mid = Math.floor(sorted.length / 2);
  const median = sorted.length % 2 === 0
    ? (sorted[mid - 1] + sorted[mid]) / 2
    : sorted[mid];

  return { sum, avg, max, min, median, count: arr.length };
}

// 示例
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(getStats(numbers));
// { sum: 55, avg: 5.5, max: 10, min: 1, median: 5.5, count: 10 }

分组统计

// 按指定条件分组统计
function groupBy(arr, keyFn) {
  return arr.reduce((groups, item) => {
    const key = typeof keyFn === 'function' ? keyFn(item) : item[keyFn];
    (groups[key] = groups[key] || []).push(item);
    return groups;
  }, {});
}

// 示例
const users = [
  { name: 'Alice', age: 25, department: 'IT' },
  { name: 'Bob', age: 30, department: 'HR' },
  { name: 'Charlie', age: 25, department: 'IT' },
  { name: 'David', age: 35, department: 'HR' }
];

// 按部门分组
console.log(groupBy(users, 'department'));
// { IT: [{...}, {...}], HR: [{...}, {...}] }

// 按年龄段分组
console.log(groupBy(users, u => u.age >= 30 ? '30+' : '30以下'));
// { '30以下': [{...}, {...}], '30+': [{...}, {...}] }

聚合统计

// 分组后进行聚合计算
function aggregate(arr, groupKey, valueKey, aggregateFn) {
  const groups = groupBy(arr, groupKey);
  const result = {};

  for (const [key, items] of Object.entries(groups)) {
    const values = items.map(item => item[valueKey]);
    result[key] = aggregateFn(values);
  }

  return result;
}

// 聚合函数
const aggregators = {
  sum: arr => arr.reduce((a, b) => a + b, 0),
  avg: arr => arr.reduce((a, b) => a + b, 0) / arr.length,
  count: arr => arr.length,
  max: arr => Math.max(...arr),
  min: arr => Math.min(...arr)
};

// 示例:统计各部门平均年龄
console.log(aggregate(users, 'department', 'age', aggregators.avg));
// { IT: 25, HR: 32.5 }

找出出现次数最多的元素

// 找出数组中出现次数最多的元素
function findMostFrequent(arr) {
  const counts = countElements(arr);
  let maxCount = 0;
  let result = null;

  for (const [item, count] of Object.entries(counts)) {
    if (count > maxCount) {
      maxCount = count;
      result = item;
    }
  }

  return { element: result, count: maxCount };
}

// 示例
console.log(findMostFrequent([1, 2, 2, 3, 3, 3, 4]));
// { element: '3', count: 3 }

关键点

  • reduce 是数据统计的核心方法,可以实现计数、求和、分组等操作
  • 统计对象时用元素作为 key,出现次数作为 value
  • 中位数需要先排序,注意奇偶数长度的处理
  • 分组统计先 groupBy,再对每组进行聚合计算
  • Math.max(...arr) 在大数组时可能栈溢出,可用 reduce 替代