简体   繁体   English

Object.keys 带来枚举的索引值

[英]Object.keys brings index values of enum

I have the following enum我有以下枚举

export enum IAgentTask {
  firstName,
  lastName,
  idNumber,
  srId,
  srCreationDate,
  selected,
  phoneNumber,
  offerId,
  clientId,
  teamName,
  userFirstName,
  userLastName,
  agentName,
  mainreferrerName
  ....
}

I need to get only the key (list of all the options as string) but using Object.keys(IAgentTask) bring a list with also the number of the property(26) like this:我只需要获取密钥(所有选项的列表作为字符串),但使用Object.keys(IAgentTask)带来一个列表,其中还包含属性 (26) 的编号,如下所示:

['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', 'firstName', 'lastName'] .....why? ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', 'firstName', 'lastName'] .....为什么?

also after using the list to compare the properties of another list- I want to remove the property of response.tasks that are not in test how can I do it dynamically?同样在使用列表比较另一个列表的属性之后-我想删除不在测试中的response.tasks的属性我怎么能动态地做呢?

example for response.tasks List of: response.tasks 列表的示例:

 agentID: 1
    agentName: ""
    bpaOfferId: null
    clientId: 974543
    companyId: null

etc....... ETC.......

if my test list is not contains ('agentID') so remove it from response.tasks如果我的test列表不包含 ('agentID') 那么将其从 response.tasks 中删除

let test = this.filteredRowsPreference.map(x => x.fieldDbKey);

for (let j = 0; j < response.tasks.length; j++) {
  let f= Object.keys(IAgentTask);
  for (let key in Object.keys(IAgentTask)) {
    if (!test.includes(key)) {
      delete response.tasks[j][key];
    }
  }
}

response.tasks[j][key] is undefined and I don't want to access every property like this: response.tasks[j].firstName response.tasks[j][key] undefined ,我不想像这样访问每个属性: response.tasks[j].firstName

Enums in TS can be accessed both by key and value. TS 中的枚举可以通过键和值来访问。 When you declare an enum and don't assign values to the keys, they automatically follow a numbered sequence.当您声明一个枚举并且不为键赋值时,它们会自动遵循一个编号序列。

If all you need is getting the list of items in the enum, a quick hack would be filtering out things that don't parse to numbers so you omit the implicit values of the enum:如果您只需要获取枚举中的项目列表,一个快速的 hack 将过滤掉不解析为数字的内容,因此您可以省略枚举的隐式值:

Object.keys(IAgentTask).filter((key) => Number.isNaN(parseInt(key, 10)))

The easiest way to address this is to use string enums , ie解决这个问题的最简单方法是使用string enums ,即

export enum IStringAgentTask {
    firstName = 'firstName',
    lastName = 'lastName',
    idNumber = 'idNumber',
    srId = 'srId',
    srCreationDate = 'srCreationDate',
    selected = 'selected',
    phoneNumber = 'phoneNumber',
    offerId = 'offerId',
    clientId = 'clientId',
    teamName = 'teamName',
    userFirstName = 'userFirstName',
    userLastName = 'userLastName',
    agentName = 'agentName',
    mainreferrerName = 'mainreferrerName',
}

Object.keys() will then yield the following: Object.keys()然后将产生以下内容:

console.log(Object.keys(IStringAgentTask))
// ["firstName", "lastName", "idNumber", "srId", "srCreationDate", "selected", "phoneNumber", "offerId", "clientId", "teamName", "userFirstName", "userLastName", "agentName", "mainreferrerName"]

However if you need to use the basic enum (ie you prefer/benefit from the numeric value of the enum), you can count on the fact that the array that is produced is twice the length of the number of enum values you have listed, as it contains all of the values (numbers) listed sequentially followed by all of the keys (the enum properties).但是,如果您需要使用基本枚举(即您更喜欢/受益于枚举的数值),您可以指望生成的数组的长度是您列出的枚举值数量的两倍,因为它包含按顺序列出的所有值(数字),后跟所有键(枚举属性)。 You can therefore just discard the first half of the array and be left with the same array as in the previous example:因此,您可以只丢弃数组的前半部分,并保留与上一个示例相同的数组:

export enum IAgentTask {
    firstName,
    lastName,
    idNumber,
    srId,
    srCreationDate,
    selected,
    phoneNumber,
    offerId,
    clientId,
    teamName,
    userFirstName,
    userLastName,
    agentName,
    mainreferrerName,
}

function getEnumValues(): string[] {
    const originalEnumValues: (string | number)[] = Object.keys(IAgentTask);
    const halfOriginalEnumValuesLength = originalEnumValues.length / 2
    return originalEnumValues.splice(halfOriginalEnumValuesLength, halfOriginalEnumValuesLength) as string[]
}

console.log(getEnumValues());
// ["firstName", "lastName", "idNumber", "srId", "srCreationDate", "selected", "phoneNumber", "offerId", "clientId", "teamName", "userFirstName", "userLastName", "agentName", "mainreferrerName"]

The second part of your question (I believe) asks for an array of objects to have all keys on each object deleted if the key does not exist in the enum list.如果枚举列表中不存在键,则问题的第二部分(我相信)要求对象数组删除每个对象上的所有键。 This could be achieved as follows:这可以通过以下方式实现:

const tasks: Record<string, any>[] = [
  {
    firstName: '',
    lastName: '',
    keyThatIsNotInTheEnum: '',
  },
  {
    agentName: '',
    agentId: 1
  }
]

function removeNonEnumKeys(tasks: Record<string, any>[]): Record<string, any>[] {
    const enumValues: string[] = Object.keys(IStringAgentTask);
    const tasksToSanitise: Record<string, any>[] = JSON.parse(JSON.stringify(tasks)); // duplicate array to prevent mutating the original

    tasksToSanitise
        .forEach(
            task => {
                Object.keys(task)
                    .forEach(key => {
                        if(!enumValues.includes(key)) { delete task[key]; }
                    });
            }
        );

    return tasksToSanitise;
}

console.log(tasks, removeNonEnumKeys(tasks));
// [{ "firstName": "", "lastName": "" }, { "agentName": "" }] 

TypeScript Playground 打字游乐场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM