有没有一种方法可以在给定值数组的情况下创建动态范围,并计算有多少属于每个范围

问题描述 投票:0回答:2

所以我有一个带有饼图的前端,想要显示我的客户的年龄百分比(数据库表)。我存储了每个客户的年龄,所以我有一个像这样的数组。

enter image description here

const ages = [12,42,23,42,12,65,75,12,43,54,12,53,24,23,54,64,76,12,42];

鉴于这些价值观,我希望最终拥有这样的东西

const data = {
    labels: ['12-20', '21-40', '41-60', '61-76']
    dataSet: [4, 6, 2, 5] // This is the amount of ages between each range. The sum of these must be equivalent of the length of the array 
}

这是我迄今为止尝试过的

const ages = [12, 42, 53, 12, 32, 12, 52, 66, 76, 87, 23, 12, 43, 12, 43, 54, 65].sort((a, b) => a - b);
const minAge = Math.min(...ages);
const maxAge = Math.max(...ages);
const q1 = ages[Math.floor(ages.length / 4)];
const q2 = ages[Math.floor(ages.length / 2)];
const q3 = ages[Math.floor(ages.length * 3 / 4)];
let firstRangeCount = 0;
let secondRangeCount = 0;
let thirdRangeCount = 0;
let fourthRangeCount = 0;
for (const age of ages) {
    if (age) {
        if (age <= q1) {
            firstRangeCount++;
        } else if (age <= q2) {
            secondRangeCount++;
        } else if (age <= q3) {
            thirdRangeCount++;
        } else {
            fourthRangeCount++;
        }
    }
}
const data = {
    labels: [
        `${minAge} - ${q1}`,
        `${q1} - ${q2}`,
        `${q2} - ${q3}`,
        `${q3} - ${maxAge}`,
    ],
    datasets: {
        label: 'Ages',
        data: [firstRangeCount, secondRangeCount, thirdRangeCount, fourthRangeCount],
    }
}

但是这个解决方案的问题是它不是动态的。如果年龄数组包含的数据较少,则不会使用 4 个范围。

我怎样才能使这个范围“动态”?我读过一些有关四分位数范围的内容,但它对我没有多大帮助

javascript arrays math pie-chart
2个回答
1
投票

尝试一下(下面的代码片段中已添加描述性注释)

// Input array
const ages = [12,42,23,42,12,65,75,12,43,54,12,53,24,23,54,64,76,12,42];

// data object with range array
const data = {
  labels: ['12-20', '21-40', '41-60', '61-76'],
  dataSet: []
}

// declare a variable which will contain the count of occurance based on the range
const obj = {};

// logic to find out the counts and pushed into an range array in an object.
data.labels.forEach(label => {
  const splittedLabel = label.split('-')
  const filteredAges = ages.filter(e => e >= splittedLabel[0] && e <= splittedLabel[1]);
  obj[label] = [];
  obj[label].push(...filteredAges);
});

// getting the length 
const dataSet = Object.values(obj).map(arr => arr.length);

data.dataSet = dataSet;

// Result
console.log(data);


0
投票

2024 中,这可以通过

Object.groupBy()
来实现,其中回调函数返回用于分组的属性名称(键)。您可以从以下开始:

const ages = [12,42,23,42,12,65,75,12,43,54,12,53,24,23,54,64,76,12,42];
const result = Object.groupBy(ages, age => `${min = Math.trunc(age / 10) * 10}-${min + 10}`);
console.log(result)
/*
{
  10-20: [12, 12, 12, 12, 12],
  40-50: [42, 42, 43, 42],
  20-30: [23, 24, 23],
  60-70: [65, 64],
  70-80: [75, 76],
  50-60: [54, 53, 54],
}
*/

排序和格式化
result

如果您希望对属性进行排序,您可以:

  • 调用
    agesOR
    之前对Object.groupBy()数组进行排序
  • result
    对象的属性进行排序。

(第一个选项适用于较小的

ages.length
数组。第二个选项适用于较大的
ages.length
数组,因为最多有约 10 个属性需要排序)

如果您只对每组的总数感兴趣,您可以:

const ages = [12,42,23,42,12,65,75,12,43,54,12,53,24,23,54,64,76,12,42];
const result = Object.groupBy(ages, age => Math.trunc(age / 10));

// sort&count ------
const sortCount = Object.fromEntries(
  Array.from(
    Object.entries(result).sort(), 
    ([k, ages]) => [`${k * 10}-${k * 10 + 10}`, ages.length]
  )
);
console.log(sortCount)
/*
{
  10-20: 5,
  20-30: 3,
  40-50: 4,
  50-60: 3,
  60-70: 2,
  70-80: 2
}
*/

// format ------
const data = {
  labels: Object.keys(sortCount),
  dataSet: Object.values(sortCount)
}
console.log(data)
/*
{
 labels: ['10-20', '20-30', '40-50', '50-60', '60-70', '70-80'],
 dataSet: [5, 3, 4, 3, 2, 2]
}
*/

© www.soinside.com 2019 - 2024. All rights reserved.