跳到主要内容

数据归类技术

单一归类

单一归类指的是一条数据只对应一个种类,这种数据的关联叫做映射。例如,下面的 JSON 数据中,每个人的性别只对应男或女其中一种:

{
"1": [
{ "id": "1", "name": "小明", "sex": "1" },
{ "id": "2", "name": "小绿", "sex": "1" }
],
"2": [
{ "id": "3", "name": "小影", "sex": "2" },
{ "id": "4", "name": "小姜", "sex": "2" }
]
}

下面是一个实现单一归类的 JavaScript 代码示例:

<script>
var users = [
{ id: '1', name: '小明', sex: '1' },
{ id: '2', name: '小绿', sex: '1' },
{ id: '3', name: '小影', sex: '2' },
{ id: '4', name: '小姜', sex: '2' },
];

var sexTypes = [
{ id: '1', sex: '男' },
{ id: '2', sex: '女' },
];

var classifiedData = {};

sexTypes.forEach(function (sexType) {
var sexId = sexType.id;

classifiedData[sexId] = [];

users.forEach(function (user) {
var userSex = user.sex;

if (userSex === sexId) {
classifiedData[sexId].push(user);
}
});
});

console.log(classifiedData);
</script>

在这个例子中,我们先定义了两个数组:users存储用户数据,sexTypes存储性别类型。然后,我们创建一个空对象classifiedData用于存储归类后的数据。

接下来,我们遍历sexTypes数组,对于每个性别类型,我们在classifiedData对象中创建一个对应的空数组。然后,我们再遍历users数组,将每个用户按照性别归类到对应的数组中。

最后,classifiedData对象就包含了按性别归类的用户数据。

复合归类

复合归类指的是一条数据可以同时属于多个种类。下面是一个复合归类的例子:

var hobbies = [
{ id: '1', name: '足球' },
{ id: '2', name: '篮球' },
{ id: '3', name: '排球' },
{ id: '4', name: '乒乓球' },
{ id: '5', name: '保龄球' },
{ id: '6', name: '高尔夫球' },
];

var persons = [
{ name: '小2', hobby: '1,3' },
{ name: '小1', hobby: '1,4' },
{ name: '小3', hobby: '1,6' },
{ name: '小4', hobby: '1,6' },
{ name: '小5', hobby: '1,3,4' },
{ name: '小6', hobby: '3,4' },
{ name: '小7', hobby: '3,5' },
{ name: '小8', hobby: '1,2,3,4,5,6' },
];

var classifiedData = {};

hobbies.forEach(function (hobby) {
var hobbyId = hobby.id;
classifiedData[hobbyId] = [];

persons.forEach(function (person) {
var personHobbies = person.hobby.split(',');

personHobbies.forEach(function (personHobby) {
if (personHobby === hobbyId) {
classifiedData[hobbyId].push(person);
}
});
});
});

console.log(classifiedData);

在这个例子中,每个人可以有多个爱好,爱好用逗号分隔的字符串表示。我们先遍历hobbies数组,为每个爱好在classifiedData对象中创建一个空数组。

然后,我们遍历persons数组,对于每个人,我们将其爱好字符串按逗号分割成数组。接下来,我们再遍历这个爱好数组,将当前人添加到对应爱好的数组中。

最终,classifiedData对象就包含了按爱好归类的人员数据,每个人可以出现在多个爱好的数组中。

封装归类函数

为了提高代码的复用性,我们可以将归类操作封装成一个函数。下面是一个封装后的归类函数示例:

function classifyData(categories, data, foreignKey, classifyType) {
var classifiedData = {};

categories.forEach(function (category) {
var categoryId = category.id;
classifiedData[categoryId] = [];

data.forEach(function (item) {
var foreignValue = item[foreignKey];

if (classifyType === 'single') {
if (foreignValue === categoryId) {
classifiedData[categoryId].push(item);
}
} else if (classifyType === 'multi') {
var foreignValues = foreignValue.split(',');
if (foreignValues.includes(categoryId)) {
classifiedData[categoryId].push(item);
}
}
});
});

return classifiedData;
}

var hobbies = [
{ id: '1', name: '足球' },
{ id: '2', name: '篮球' },
{ id: '3', name: '排球' },
{ id: '4', name: '乒乓球' },
{ id: '5', name: '保龄球' },
{ id: '6', name: '高尔夫球' },
];

var persons = [
{ name: '小2', hobby: '1,3' },
{ name: '小1', hobby: '1,4' },
{ name: '小3', hobby: '1,6' },
{ name: '小4', hobby: '1,6' },
{ name: '小5', hobby: '1,3,4' },
{ name: '小6', hobby: '3,4' },
{ name: '小7', hobby: '3,5' },
{ name: '小8', hobby: '1,2,3,4,5,6' },
];

var hobbyData = classifyData(hobbies, persons, 'hobby', 'multi');
console.log(hobbyData);

classifyData函数接受四个参数:

  1. categories:归类的类别数组
  2. data:需要归类的数据数组
  3. foreignKey:外键,即data中用于归类的属性名
  4. classifyType:归类类型,可以是'single''multi',表示单一归类或复合归类

函数内部先创建一个空对象classifiedData用于存储归类后的数据。然后,它遍历categories数组,为每个类别在classifiedData中创建一个空数组。

接下来,函数遍历data数组,对于每个数据项,根据classifyType的值进行单一归类或复合归类。单一归类直接判断外键值是否等于当前类别的 ID,复合归类则将外键值按逗号分割成数组,判断当前类别的 ID 是否在数组中。

最后,函数返回归类后的数据对象classifiedData

使用封装后的classifyData函数,我们可以方便地对不同的数据进行归类。上面的代码示例演示了如何使用classifyData函数对人员数据按爱好进行复合归类。

通过封装归类函数,我们提高了代码的复用性和可维护性。无论是单一归类还是复合归类,都可以使用同一个函数来完成,只需传入不同的参数即可。