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,
      },
    ],
  },
];

解题思路:

  1. 遍历原数组,将每个 list 中的对象按照其前后关系归类到一个新的对象中,该新对象的 keyouterIdvalue 为包含该 outerIdlist 中的对象数组。
  2. 对新对象中的每个 key 所对应的 value 数组进行排序,排序的规则是根据其 preIdnextId,找到相应的对象,然后比较其在原数组中的位置。
  3. 将排序后的 value 数组中的每个对象的 outerId 属性设置为其所属的 key 值。
  4. 根据新对象中的每个 key-value 对,生成一个新的数组对象,该数组对象中的每个元素都是一个包含 idlist 属性的对象,其中 idkey 值,listvalue 值。

代码实现:

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);
JavaScript 数组对象排序:根据前后关系重新排列数组

原文地址: https://www.cveoy.top/t/topic/otAT 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录