按键过滤对象属性,但将过滤后的键保留在白名单中为空。

3
我需要一些帮助来按键过滤对象属性,但保留白名单中的过滤键为空。
我正在使用SO上的这个答案中的函数:

https://dev59.com/21kT5IYBdhLWcg3wV-CY#38750895

预览:

const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const allowed = ['item1', 'item3'];

const filtered = Object.keys(raw)
  .filter(key => allowed.includes(key))
  .reduce((obj, key) => {
    obj[key] = raw[key];
    return obj;
  }, {});

console.log(filtered);

在我的方案中,我将其作为白名单:

var whitelist = ["ApartmentNumber", "FloorSpace", "PrimaryRoomSpace", "CaseStatusType", "AskingPrice"];

这是原始对象:

{
    "Id": 668,
    "ProjectId": 667,
    "NumberOfBedrooms": 2,
    "FloorSpace": 60,
    "PrimaryRoomSpace": 60,
    "LandLotType": "None",
    "ApartmentNumber": "L-101\r",
    "PublicationTitle": "L-101",
    "PublicationInformationId": 49,
    "CaseStatusId": 227,
    "CaseStatusType": "Ready",
    "CaseStatusName": "Salgsklar",
    "CaseReferralKey": "80-17-10001",
    "AskingPrice": 10000000,
    "EnergyLabel": "None",
    "HeatingGrade": "None",
    "Comission": 0,
    "DocumentCostBasis": 10000000,
    "PricePerSquareMeter": 166666.66666666666666666667,
    "Street": "Street 1",
    "ZipCode": "0682",
    "BuyerIds": [],
    "ResponsibleBrokerId": 0,
    "BrokerId": 0
},
{
    "Id": 669,
    "ProjectId": 667,
    "NumberOfBedrooms": 2,
    "NumberOfBedroomsMax": 2,
    "FloorSpace": 0,
    "FloorSpaceMax": 100,
    "PrimaryRoomSpace": 90,
    "PrimaryRoomSpaceMax": 90,
    "ApartmentNumber": "L-107\r",
    "CaseStatusId": 207,
    "CaseStatusType": "Active",
    "CaseStatusName": "Oppdrag akseptert",
    "CaseReferralKey": "80-17-10007",
    "StoreyOf": 1,
    "EnergyLabel": "None",
    "HeatingGrade": "None",
    "Comission": 0,
    "DocumentCostBasis": 0,
    "Street": "Street 2",
    "ZipCode": "0682",
    "BuyerIds": [],
    "ResponsibleBrokerId": 0,
    "BrokerId": 0
},
{
    "Id": 670,
    "ProjectId": 667,
    "NumberOfBedrooms": 2,
    "NumberOfBedroomsMax": 2,
    "FloorSpace": 0,
    "FloorSpaceMax": 100,
    "PrimaryRoomSpace": 90,
    "PrimaryRoomSpaceMax": 90,
    "ApartmentNumber": "L-106\r",
    "CaseStatusId": 223,
    "CaseStatusType": "General",
    "CaseStatusName": "Bestilt info",
    "CaseReferralKey": "80-17-10006",
    "StoreyOf": 1,
    "EnergyLabel": "None",
    "HeatingGrade": "None",
    "Comission": 0,
    "DocumentCostBasis": 0,
    "Street": "Street 1",
    "ZipCode": "0682",
    "BuyerIds": [],
    "ResponsibleBrokerId": 0,
    "BrokerId": 0
},
{
    "Id": 671,
    "ProjectId": 667,
    "NumberOfBedroomsMax": 1,
    "FloorSpace": 0,
    "FloorSpaceMax": 50,
    "ApartmentNumber": "L-102\r",
    "CaseStatusId": 219,
    "CaseStatusType": "General",
    "CaseStatusName": "All info mottatt",
    "CaseReferralKey": "80-17-10002",
    "StoreyOf": 2,
    "EnergyLabel": "None",
    "HeatingGrade": "None",
    "Comission": 0,
    "DocumentCostBasis": 0,
    "PricePerSquareMeter": 0,
    "Street": "Street 1",
    "ZipCode": "0682",
    "BuyerIds": [],
    "ResponsibleBrokerId": 0,
    "BrokerId": 0
}

这是第一个对象的过滤函数输出,对我很有用,因为它包含白名单中所有值:
{ ApartmentNumber: 'L-101\r',
  FloorSpace: 60,
  PrimaryRoomSpace: 60,
  CaseStatusType: 'Ready',
  AskingPrice: 10000000 }

但对于第二个对象,它会看起来像这样。由于第二个对象中没有AskingPrice,因此它缺失了:

{ ApartmentNumber: 'L-107\r',
  FloorSpace: 0,
  PrimaryRoomSpace: 90,
  CaseStatusType: 'Active' }

问题在于我需要筛选出白名单中存在的键,它们不能被删除。如果在原始对象中不存在,则希望它们为空。
为了澄清,我需要第二个对象看起来像这样:
{ ApartmentNumber: 'L-107\r',
  FloorSpace: 0,
  PrimaryRoomSpace: 90,
  CaseStatusType: 'Active',
  AskingPrice: ''} //<-- empty string

如何调整过滤函数以实现此功能?
4个回答

3

由于您需要在filtered对象中使用所有允许的键,因此可以循环遍历allowed数组,并检查白名单键是否存在于您的原始对象中,如果不存在,则添加带有null或所需值的键。以下是示例代码。

const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
};

const allowed = ['item1', 'item3'];

let filtered = {}

allowed.forEach( key => {
  filtered[key] = (typeof raw[key] === 'undefined') ? '' : raw[key];
})

console.log(filtered);

正如@GrégoryNEUT所指出的那样,请注意我们正在使用的条件,它不会删除具有nullfalse0值的键。如果您想要删除所有这些类型的值,请使用下面给出的条件。
filtered[key] = raw[key] ? {} : raw[key];

2
请使用 typeof raw[key] === 'undefined'。使用 raw[key] === undefined 比较 raw[key] 和变量 undefined,但是 undefined 是不存在的。如果在之前执行 const undefined = 50;,那么它就不再起作用了。此外,filtered 是一个 const - Orelsanpls
@GrégoryNEUT,感谢您指出这一点。我已经在答案中进行了更改。 - Raghav Garg
@GrégoryNEUT 嗯,也不需要写raw[key] === 'undefined',如果你使用raw[key]作为条件,它没有定义时条件就不会被满足。 - cнŝdk
1
@chsdk 是的,但如果 raw[key] = falseraw[key] = 0,你就会有一些问题。 - Orelsanpls
@veb,请接受答案,如果它回答了你的问题,否则请更详细地解释你的问题。 - Raghav Garg

0

应该可以了。 使用Array.prototype.reduce

const raw = [{
    "Id": 668,
    "ProjectId": 667,
    "NumberOfBedrooms": 2,
    "FloorSpace": 60,
    "PrimaryRoomSpace": 60,
    "LandLotType": "None",
    "ApartmentNumber": "L-101\r",
    "PublicationTitle": "L-101",
    "PublicationInformationId": 49,
    "CaseStatusId": 227,
    "CaseStatusType": "Ready",
    "CaseStatusName": "Salgsklar",
    "CaseReferralKey": "80-17-10001",
    "AskingPrice": 10000000,
    "EnergyLabel": "None",
    "HeatingGrade": "None",
    "Comission": 0,
    "DocumentCostBasis": 10000000,
    "PricePerSquareMeter": 166666.66666666666666666667,
    "Street": "Street 1",
    "ZipCode": "0682",
    "BuyerIds": [],
    "ResponsibleBrokerId": 0,
    "BrokerId": 0
  },
  {
    "Id": 669,
    "ProjectId": 667,
    "NumberOfBedrooms": 2,
    "NumberOfBedroomsMax": 2,
    "FloorSpace": 0,
    "FloorSpaceMax": 100,
    "PrimaryRoomSpace": 90,
    "PrimaryRoomSpaceMax": 90,
    "ApartmentNumber": "L-107\r",
    "CaseStatusId": 207,
    "CaseStatusType": "Active",
    "CaseStatusName": "Oppdrag akseptert",
    "CaseReferralKey": "80-17-10007",
    "StoreyOf": 1,
    "EnergyLabel": "None",
    "HeatingGrade": "None",
    "Comission": 0,
    "DocumentCostBasis": 0,
    "Street": "Street 2",
    "ZipCode": "0682",
    "BuyerIds": [],
    "ResponsibleBrokerId": 0,
    "BrokerId": 0
  },
  {
    "Id": 670,
    "ProjectId": 667,
    "NumberOfBedrooms": 2,
    "NumberOfBedroomsMax": 2,
    "FloorSpace": 0,
    "FloorSpaceMax": 100,
    "PrimaryRoomSpace": 90,
    "PrimaryRoomSpaceMax": 90,
    "ApartmentNumber": "L-106\r",
    "CaseStatusId": 223,
    "CaseStatusType": "General",
    "CaseStatusName": "Bestilt info",
    "CaseReferralKey": "80-17-10006",
    "StoreyOf": 1,
    "EnergyLabel": "None",
    "HeatingGrade": "None",
    "Comission": 0,
    "DocumentCostBasis": 0,
    "Street": "Street 1",
    "ZipCode": "0682",
    "BuyerIds": [],
    "ResponsibleBrokerId": 0,
    "BrokerId": 0
  },
  {
    "Id": 671,
    "ProjectId": 667,
    "NumberOfBedroomsMax": 1,
    "FloorSpace": 0,
    "FloorSpaceMax": 50,
    "ApartmentNumber": "L-102\r",
    "CaseStatusId": 219,
    "CaseStatusType": "General",
    "CaseStatusName": "All info mottatt",
    "CaseReferralKey": "80-17-10002",
    "StoreyOf": 2,
    "EnergyLabel": "None",
    "HeatingGrade": "None",
    "Comission": 0,
    "DocumentCostBasis": 0,
    "PricePerSquareMeter": 0,
    "Street": "Street 1",
    "ZipCode": "0682",
    "BuyerIds": [],
    "ResponsibleBrokerId": 0,
    "BrokerId": 0
  }
]

const whitelist = ["ApartmentNumber", "FloorSpace", "PrimaryRoomSpace", "CaseStatusType", "AskingPrice"];

raw.forEach(obj => {
  const filtered = whitelist.reduce((acc, key) => {
    if(key in obj) {
      acc[key] = obj[key]
    } else {
      acc[key] = null
    }
    return acc
  }, {})


  console.log(filtered);
})


我猜,这不是OP想要的结果。 - Raghav Garg
@RaghavGarg,是的,你是对的。我完全理解错了。已更新答案。 - lukaleli

0

你可以用更简单的方式实现它。

var input = [
 {
  "Id" : 668,
  "ProjectId" : 667,
  "NumberOfBedrooms" : 2,
  "FloorSpace" : 60,
  "PrimaryRoomSpace" : 60,
  "LandLotType" : "None",
  "ApartmentNumber" : "L-101\r",
  "PublicationTitle" : "L-101",
  "PublicationInformationId" : 49,
  "CaseStatusId" : 227,
  "CaseStatusType" : "Ready",
  "CaseStatusName" : "Salgsklar",
  "CaseReferralKey" : "80-17-10001",
  "AskingPrice" : 10000000,
  "EnergyLabel" : "None",
  "HeatingGrade" : "None",
  "Comission" : 0,
  "DocumentCostBasis" : 10000000,
  "PricePerSquareMeter" : 166666.66666666666666666667,
  "Street" : "Street 1",
  "ZipCode" : "0682",
  "BuyerIds" : [],
  "ResponsibleBrokerId" : 0,
  "BrokerId" : 0
 },
 {
  "Id" : 669,
  "ProjectId" : 667,
  "NumberOfBedrooms" : 2,
  "NumberOfBedroomsMax" : 2,
  "FloorSpace" : 0,
  "FloorSpaceMax" : 100,
  "PrimaryRoomSpace" : 90,
  "PrimaryRoomSpaceMax" : 90,
  "ApartmentNumber" : "L-107\r",
  "CaseStatusId" : 207,
  "CaseStatusType" : "Active",
  "CaseStatusName" : "Oppdrag akseptert",
  "CaseReferralKey" : "80-17-10007",
  "StoreyOf" : 1,
  "EnergyLabel" : "None",
  "HeatingGrade" : "None",
  "Comission" : 0,
  "DocumentCostBasis" : 0,
  "Street" : "Street 2",
  "ZipCode" : "0682",
  "BuyerIds" : [],
  "ResponsibleBrokerId" : 0,
  "BrokerId" : 0
 },
 {
  "Id" : 670,
  "ProjectId" : 667,
  "NumberOfBedrooms" : 2,
  "NumberOfBedroomsMax" : 2,
  "FloorSpace" : 0,
  "FloorSpaceMax" : 100,
  "PrimaryRoomSpace" : 90,
  "PrimaryRoomSpaceMax" : 90,
  "ApartmentNumber" : "L-106\r",
  "CaseStatusId" : 223,
  "CaseStatusType" : "General",
  "CaseStatusName" : "Bestilt info",
  "CaseReferralKey" : "80-17-10006",
  "StoreyOf" : 1,
  "EnergyLabel" : "None",
  "HeatingGrade" : "None",
  "Comission" : 0,
  "DocumentCostBasis" : 0,
  "Street" : "Street 1",
  "ZipCode" : "0682",
  "BuyerIds" : [],
  "ResponsibleBrokerId" : 0,
  "BrokerId" : 0
 },
 {
  "Id" : 671,
  "ProjectId" : 667,
  "NumberOfBedroomsMax" : 1,
  "FloorSpace" : 0,
  "FloorSpaceMax" : 50,
  "ApartmentNumber" : "L-102\r",
  "CaseStatusId" : 219,
  "CaseStatusType" : "General",
  "CaseStatusName" : "All info mottatt",
  "CaseReferralKey" : "80-17-10002",
  "StoreyOf" : 2,
  "EnergyLabel" : "None",
  "HeatingGrade" : "None",
  "Comission" : 0,
  "DocumentCostBasis" : 0,
  "PricePerSquareMeter" : 0,
  "Street" : "Street 1",
  "ZipCode" : "0682",
  "BuyerIds" : [],
  "ResponsibleBrokerId" : 0,
  "BrokerId" : 0
 }
];
var whitelist = [
 "ApartmentNumber",
 "FloorSpace",
 "PrimaryRoomSpace",
 "CaseStatusType",
 "AskingPrice"
];
var output = input.map((item) => {
 var out = {};
 whitelist.forEach((key) => {
  out[key] = key in item ? item[key] : '';
 });
 return out;
});
console.log(output);


0

不要循环遍历Object.keys(raw),而是循环遍历allowed键,这样您就可以确保保留所有允许的属性。

const filtered = {}

allowed.forEach((key) => {
  filtered[key] = (typeof raw[key] !== 'undefined') ? raw[key] : '';
});

演示:

const raw = {
  item1: {
    key: 'sdfd',
    value: 'sdfd'
  },
  item2: {
    key: 'sdfd',
    value: 'sdfd'
  },
  item3: {
    key: 'sdfd',
    value: 'sdfd'
  }
};

const allowed = ['item1', 'item3', 'item4'];

const filtered = {}

allowed.forEach((key) => {
  filtered[key] = (typeof raw[key] !== 'undefined') ? raw[key] : '';
});

console.log(filtered);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接