JavaScript 数组对象排序:根据前后关系重新排列数组
JavaScript 数组对象排序:根据前后关系重新排列数组
问题描述:
现有数组对象如下:
const originalArray = [
{
id: 1,
list: [
{
preId: '',
nextId: '',
id: 'N1',
},
],
},
{
id: 2,
list: [
{
preId: 'N4',
nextId: '',
id: 'N2',
},
],
},
{
id: 3,
list: [
{
preId: '',
nextId: 'N6',
id: 'N3',
},
],
},
{
id: 4,
list: [
{
preId: 'N6',
nextId: 'N2',
id: 'N4',
},
],
},
{
id: 5,
list: [
{
preId: '',
nextId: '',
id: 'N5',
},
],
},
{
id: 6,
list: [
{
preId: 'N3',
nextId: 'N4',
id: 'N6',
},
],
},
];
条件:
list对象中:preId代表排序在该对象前面的对象的id;nextId: 代表排序在该对象后面的对象的id;
目的:
- 需要重新筛选排列该数组,根据每个对象中
list对象将有前后关系的对象归类,造出一个新数组对象; list中对象是拥有先后顺序,且list中用outerId来记录属于原来外层的id。
处理完成后的数组如下:
[
{
id: 1,
list: [
{
preId: '',
nextId: '',
id: 'N1',
outerId: 1,
},
],
},
{
id: 3,
list: [
{
preId: '',
nextId: 'N6',
id: 'N3',
outerId: 3,
},
{
preId: 'N3',
nextId: 'N4',
id: 'N6',
outerId: 6,
},
{
preId: 'N6',
nextId: 'N2',
id: 'N4',
outerId: 4,
},
{
preId: 'N4',
nextId: '',
id: 'N2',
outerId: 2,
},
],
},
{
id: 5,
list: [
{
preId: '',
nextId: '',
id: 'N5',
outerId: 5,
},
],
},
];
解题思路:
- 遍历原数组,将每个
list中的对象按照其前后关系归类到一个新的对象中,该新对象的key为outerId,value为包含该outerId的list中的对象数组。 - 对新对象中的每个
key所对应的value数组进行排序,排序的规则是根据其preId和nextId,找到相应的对象,然后比较其在原数组中的位置。 - 将排序后的
value数组中的每个对象的outerId属性设置为其所属的key值。 - 根据新对象中的每个
key-value对,生成一个新的数组对象,该数组对象中的每个元素都是一个包含id和list属性的对象,其中id为key值,list为value值。
代码实现:
const originalArray = [
{
id: 1,
list: [
{
preId: '',
nextId: '',
id: 'N1',
},
],
},
{
id: 2,
list: [
{
preId: 'N4',
nextId: '',
id: 'N2',
},
],
},
{
id: 3,
list: [
{
preId: '',
nextId: 'N6',
id: 'N3',
},
],
},
{
id: 4,
list: [
{
preId: 'N6',
nextId: 'N2',
id: 'N4',
},
],
},
{
id: 5,
list: [
{
preId: '',
nextId: '',
id: 'N5',
},
],
},
{
id: 6,
list: [
{
preId: 'N3',
nextId: 'N4',
id: 'N6',
},
],
},
];
// 生成新对象
const newObj = {};
originalArray.forEach((item) => {
item.list.forEach((listItem) => {
const outerId = item.id;
if (!newObj[outerId]) {
newObj[outerId] = [];
}
newObj[outerId].push({ ...listItem, outerId });
});
});
// 对新对象中的每个value数组进行排序
Object.keys(newObj).forEach((key) => {
const value = newObj[key];
value.sort((a, b) => {
let preA = null;
let preB = null;
let nextA = null;
let nextB = null;
if (a.preId) {
preA = originalArray
.flatMap((item) => item.list)
.find((item) => item.id === a.preId);
}
if (b.preId) {
preB = originalArray
.flatMap((item) => item.list)
.find((item) => item.id === b.preId);
}
if (a.nextId) {
nextA = originalArray
.flatMap((item) => item.list)
.find((item) => item.id === a.nextId);
}
if (b.nextId) {
nextB = originalArray
.flatMap((item) => item.list)
.find((item) => item.id === b.nextId);
}
if (!preA && !preB && !nextA && !nextB) {
return 0;
}
if (!preA && !preB && nextA && !nextB) {
return -1;
}
if (!preA && !preB && !nextA && nextB) {
return 1;
}
if (preA && !preB && !nextA && !nextB) {
return -1;
}
if (!preA && preB && !nextA && !nextB) {
return 1;
}
if (!preA && !preB && nextA && nextB) {
return -1;
}
if (preA && !preB && !nextA && nextB) {
return -1;
}
if (!preA && preB && nextA && !nextB) {
return 1;
}
if (!preA && !preB && nextA && !nextB) {
return -1;
}
if (preA && preB) {
const preAIndex = originalArray
.flatMap((item) => item.list)
.findIndex((item) => item.id === preA.id);
const preBIndex = originalArray
.flatMap((item) => item.list)
.findIndex((item) => item.id === preB.id);
if (preAIndex < preBIndex) {
return -1;
} else {
return 1;
}
}
if (nextA && nextB) {
const nextAIndex = originalArray
.flatMap((item) => item.list)
.findIndex((item) => item.id === nextA.id);
const nextBIndex = originalArray
.flatMap((item) => item.list)
.findIndex((item) => item.id === nextB.id);
if (nextAIndex < nextBIndex) {
return -1;
} else {
return 1;
}
}
});
});
// 将新对象转换为数组
const newArray = Object.keys(newObj).map((key) => ({
id: key,
list: newObj[key],
}));
console.log(newArray);
原文地址: https://www.cveoy.top/t/topic/otAT 著作权归作者所有。请勿转载和采集!