如何从传播运算符中删除属性?

Posted

技术标签:

【中文标题】如何从传播运算符中删除属性?【英文标题】:How to delete property from spread operator? 【发布时间】:2019-10-02 23:40:10 【问题描述】:

我想从响应中删除 drugName,但不知道 main.js

  const transformedResponse = transformResponse(response);
  const loggerResponse = ...transformedResponse;
  delete loggerResponse[drugName];
  console.log("LOGGER>>>>", loggerResponse);
  logger().info('Drug Price Response=',  ...loggerResponse, memberId: memberId, pharmacyId: pharmacyId );

\ 数据

LOGGER>>>> 
    '0': 
        isBrand: false,
        drugName: 'test drug',
        drugStrength: '5 mg 1 5 mg',
        drugForm: 'Tablet',
    

转换响应

[
    drugName: 'HYDROCODONE-HOMATROPINE MBR',
    drugStrength: '5MG-1.5MG',
    drugForm: 'TABLET',
    brand: false
]

【问题讨论】:

您的代码中没有 drugName 变量。如果你想删除drugName,那么delete loggerResponse.drugName? @adiga 我试过它没有删除我添加了数据它是如何来自服务的 请发布transformedResponse 的样本。它是一个数组吗?因为,loggerResponse中有一个0 @adiga 是的,这是我添加到问题中的数组 您的预期输出是什么? transformedResponse 总是有一个项目吗? 【参考方案1】:

const myObject = 
  a: 1,
  b: 2,
  c: 3
;
const 
  b,
  ...noB // assigns remaining keys to a new `noB` object
 = myObject;
console.log(noB); // =>  a: 1, c: 3 

【讨论】:

如果你能解释一下你的代码会解决这个问题,那将会很有帮助。换句话说,添加一些 cmets,以便我们了解您的代码的作用...... 只有几行js代码。我认为不需要任何解释。应该试试。 @Klaasiek - 非常直截了当 - 他将原始对象解构为两个对象:一个包含不需要的密钥,另一个包含剩余的密钥。然后,他使用包含剩余密钥的那个。非常简洁的代码。 不应该叫noB吗? 请记住,由于 javascript 非常有趣,这不会进行深度复制。这意味着如果您使用此方法,并且 myObject 发生突变(例如,诸如 myObject.d.moreStuff 之类的子对象稍后发生更改),noB 对象也将被更改。 Lodash 的省略可能有办法解决它(如果没有,你可以事先使用 lodash cloneDeep 来缓解)。买家当心:)【参考方案2】:

您可以使用扩展运算符并将undefined 分配给您不想要的键:

const transformedResponse = [
drugName: 'HYDROCODONE-HOMATROPINE MBR',
drugStrength: '5MG-1.5MG',
drugForm: 'TABLET',
brand: false
];

const output = transformedResponse.map((response) => (
  ...response,
  drugName: undefined
))

console.log(output);

【讨论】:

关闭但不完全在那里,注意!如果我们使用 if(drugname in output) 将结果为 true,您需要比较 VALUE,drugName 键仍然存在!【参考方案3】:

这是我发现的最简洁和不变的方式。您只需将对象分解为两部分:一部分是您要删除的属性(在本例中为drugName),另一部分是您要保留的对象的其余部分(drugWithoutName in本例)。

完成此操作后,您可以放弃已删除的属性,放弃原始对象,并使用包含所有剩余字段的新对象(在本例中为 drugWithoutName)。

想出语法并不明显,但一旦你看到它就有意义:

const response = [
    drugName: 'HYDROCODONE-HOMATROPINE MBR',
    drugStrength: '5MG-1.5MG',
    drugForm: 'TABLET',
    brand: false
]

console.log("response", response)

const removeNamesFromResponse = (response) => 
  return response.map(drug => 
    const  drugName, ...drugWithoutName  = drug
    return drugWithoutName
  )


const responseWithoutNames = removeNamesFromResponse(response)

console.log("responseWithoutNames", responseWithoutNames)

这些文章进一步解释了这个概念:

https://codeburst.io/use-es2015-object-rest-operator-to-omit-properties-38a3ecffe90

https://github.com/airbnb/javascript/blob/master/README.md#objects--rest-spread

【讨论】:

【参考方案4】:

使用 ES9 Object Rest Operator 的 1 行解决方案

const loggerResponse = 
  "0": 
    isBrand: false,
    drugName: "test drug",
    drugStrength: "5 mg 1 5 mg",
    drugForm: "Tablet",
  ,
;
const  drugName, ...newResponse  = loggerResponse["0"];
console.log(newResponse);

【讨论】:

支持一个班轮并教我一些新东西,谢谢! 有没有办法在另一个对象中做到这一点?【参考方案5】:

另一种选择是编写一个通用函数,removeKey -

const removeKey = (k,  [k]:_, ...o ) =>
  o

const values =
  [  a: 1, x: 1 
  ,  a: 1, y: 1 
  ,  a: 1, z: 1 
  ]

console .log (values .map (v => removeKey ("a", v)))
// [  x: 1 ,  y: 1 ,  z: 1  ]

如有必要,该功能可以轻松调整为删除多个键 -

const removeKey = (k = "",  [k]:_, ...o  = ) =>
  o

const removeKeys = (keys = [], o = ) =>
  keys .reduce ((r, k) => removeKey (k, r), o)

const values =
  [  a: 1, x: 1 
  ,  a: 1, y: 1 
  ,  a: 1, z: 1 
  ]

console .log (values .map (v => removeKeys (['a', 'z'], v)))
// [  x: 1 ,  y: 1 ,  ]

【讨论】:

惊人的答案,希望我能多次投票。 谢谢,removeKey 很短,可用于删除变量键【参考方案6】:

如果您在transformedResponse 数组的每个对象中都有属性drugName,您可以使用Array.map() 生成一个没有drugName 属性的新数组:

示例:

const transformedResponse = [
  
    drugName: 'HYDROCODONE-HOMATROPINE MBR',
    drugStrength: '5MG-1.5MG',
    drugForm: 'TABLET',
    brand: false
  ,
  
    drugName: 'TEST',
    drugStrength: '7MG-1.9MG',
    drugForm: 'TABLET',
    brand: false
  
];

const loggerResponse = transformedResponse.map(o =>

    let clone = Object.assign(, o);
    return (delete clone.drugName, clone);
);

console.log(loggerResponse);
.as-console background-color:black !important; color:lime;
.as-console-wrapper max-height:100% !important; top:0;

【讨论】:

【参考方案7】:

您可以使用Rest syntax in Object Destructuring 将除drugName 之外的所有属性添加到rest 变量中,如下所示:

const transformedResponse = [
    drugName: 'HYDROCODONE-HOMATROPINE MBR',
    drugStrength: '5MG-1.5MG',
    drugForm: 'TABLET',
    brand: false
,

    drugName: 'HYDROCODONE ABC',
    drugStrength: '10MG',
    drugForm: 'SYRUP',
    brand: true
]

const output = transformedResponse.map(( drugName, ...rest ) => rest)

console.log(output)

另外,当你在 中展开一个数组时,你会得到一个对象,其中数组的索引作为键,数组的值作为值。这就是为什么你会在loggerResponse 中获得一个以0 作为键的对象:

const array = [ id: 1 ,  id: 2 ]
console.log( ...array )

【讨论】:

我认为“休息模式”是区分...rest 的有用方法,因为它在此处与“休息参数”和“传播参数”使用。很好很干净的答案。 @adiga 是否有可能破坏多个属性,例如 drugName,drugForm, ...rest ,我尝试了它唯一的删除 drugName @hussain 应该可以工作:transformedResponse.map(( drugName, drugForm, ...rest ) => rest) 检查属性的大小写。 ` "drugPrice": [ "isBrand": true, "drugName": "Lipitor", "drugStrength": "80 mg", "drugForm": "Tablet", "mailPrice": "copayEmployer": 0]` 好的,我实际上试图删除 mailPrice.copayEmployer 并且没有被删除它是嵌套对象 @hussain 为此,您必须单独解构嵌套属性。像这样:jsfiddle.net/adigas/c8n2fu4a/1。你可以解构参数本身,或者,如果太混乱,你可以在map中取单独的变量@

以上是关于如何从传播运算符中删除属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ES6 扩展运算符和剩余运算符从数组或对象中删除特定元素

由于 javascript 传播运算符,Webpack 未构建

为啥 C# 6.0 在使用 Null 传播运算符时不允许设置非 null 可空结构的属性?

为啥 C# 6.0 在使用 Null 传播运算符时不允许设置非 null 可空结构的属性?

表达式树 lambda 可能不包含空传播运算符

使用扩展运算符从 ES6 中的对象中删除目标参数