使用可变过滤器从json对象中删除项目

时间:2018-10-09 14:42:41

标签: javascript node.js

我得到了一个带有3个“行会”的json文件。这些行会有一个ID和一个包含角色ID的数组。

[
  {
    "id": 1, // This is the id of a guild
    "roleIds": [
      1,
      2,
      3
    ]
  },
  {
    "id": 2,
    "roleIds": [
      4,
      5,
      6
    ]
  },
  {
    "id": 3,
    "roleIds": [
      7,
      8,
      9
    ]
  }
]

另一方面,我有一个客户持有另一个带有行会和角色的json对象。如果客户端上不存在角色ID,则数据不一致。 然后,我想从json文件中删除ID。

通常我使用array.filter(element => element.id !== targetId);

从数组中删除项目
const guilds = fs.readFileSync(file);
const targetGuild = guilds.find(guild => guild.id == targetGuildid);
let targetRoleIds = targetGuild.roleIds;

targetRoleIds.forEach(targetRoleId => {
  if (!roleIdExists(guild, targetRoleId)) {
    targetRoleIds = targetRoleIds.filter(id => id != targetRoleId);
  }
});

fs.writeFileSync(file, JSON.stringify(guilds));

使用targetRoleIds = targetRoleIds.filter(id => id != targetRoleId);不会影响guilds对象。

如何进行变异?

3 个答案:

答案 0 :(得分:0)

使用findIndex,然后直接修改对象?不知道这是否正是您想要的。

let guilds = [ { "id": 1, "roleIds": [ 1, 2, 3 ] }, { "id": 2, "roleIds": [ 4, 5, 6 ] }, { "id": 3, "roleIds": [ 7, 8, 9 ] }];

let guild = { "id": 1, "roleIds": [ 1, 2, 3 ] }

let targetId = 1; // mock
const roleIdExists = id => [1,7,8].includes(id); // mock
console.log('guilds',guilds.length);
let i = guilds.findIndex(guild => {
  console.log('guild',guild);
  return guild.id === targetId;
});
if(i===-1)
  throw Error('No guild!')
let targetRoleIds = guilds[i].roleIds;

targetRoleIds.forEach(targetRoleId => {
  if (!roleIdExists(guild, targetRoleId)) {
    guilds[i].targetRoleIds = targetRoleIds.filter(id => id != targetRoleId);
  }
});

console.log(guilds[0])

答案 1 :(得分:0)

如果我正确理解了您的问题,则希望通过每个对象的属性值过滤对象数组。如果是正确的话,则可以通过对filter方法使用分解分配来获取要比较的每个对象的属性,从而简化操作。

参见下文:

const guilds = [
  {
    id: 1, // This is the id of a guild
    roleIds: [1, 2, 3]
  },
  {
    id: 2,
    roleIds: [4, 5, 6]
  },
  {
    id: 3,
    roleIds: [7, 8, 9]
  }
];

const targetGuildid = 2;

// Use destructuring assignment to get the `id` for each object
// and then filter the array based on the comparison to the target ID.
const filtered = guilds.filter(({id}) => id !== targetGuildid);

console.log(filtered);

旁注:在节点中,导入JSON文件时,您只需要文件即可,它将自动解析为对象:const obj = require('./foo.json')const obj = require('./foo')也可以工作。

回到原始代码中,需要注意一些问题,但主要的问题是guilds本身从未修改,因此在写入文件时也不会有所不同。

答案 2 :(得分:0)

真的,您的代码非常混乱:

  1. 您读取了文件并将其分配给guilds变量,但最后写了相同的变量而没有修改。
  2. 在行代码if (!roleIdExists(guild, targetRoleId))中,我不知道如何获取guild变量。

请检查您的代码。我留下了我所理解的代码

let guilds = fs.readFileSync(file);
guilds = guilds.map((guild) => {
  if (guild.id === targetGuildId) {
    guild.roleIds = guild.roleIds.filter((roleId) => targetGuildRoles.includes(roleId));
  }
  return guild;
})

fs.writeFileSync(file, JSON.stringify(guilds));