Javascript 从值等于零的对象中删除属性

Javascript 从值等于零的对象中删除属性,javascript,arrays,functional-programming,Javascript,Arrays,Functional Programming,我试图用函数编程方法编写一个函数,它只使用map(),reduce(),filter()。这是我最好的方法,但不起作用 removeZero({ a: 0, b: 1, c: -1 }) output: removeZero({ b: 1, c: -1 }) 你知道怎么解决这个问题吗?你很接近了。这是可行的,并且主要是功能性的(我认为;我根本不太了解函数式编程的习惯用法),但除非使用Object.defineProperty来定义属性,我认为在最后一步(设置道具)中,您必须执行命令: c

我试图用函数编程方法编写一个函数,它只使用
map()
reduce()
filter()
。这是我最好的方法,但不起作用

removeZero({ a: 0, b: 1, c: -1 })

output:

removeZero({ b: 1, c: -1 })

你知道怎么解决这个问题吗?

你很接近了。这是可行的,并且主要是功能性的(我认为;我根本不太了解函数式编程的习惯用法),但除非使用
Object.defineProperty
来定义属性,我认为在最后一步(设置道具)中,您必须执行命令:

const removeZero=item=>(
对象
.钥匙(项目)
.filter(键=>项[键]!==0)
.reduce((newObj,key)=>{
newObj[key]=项目[key];
返回newObj;
}, {})
);
const result=removeZero({a:0,b:1,c:-1});

控制台日志(结果)你很接近了。这是可行的,并且主要是功能性的(我认为;我根本不太了解函数式编程的习惯用法),但除非使用
Object.defineProperty
来定义属性,我认为在最后一步(设置道具)中,您必须执行命令:

const removeZero=item=>(
对象
.钥匙(项目)
.filter(键=>项[键]!==0)
.reduce((newObj,key)=>{
newObj[key]=项目[key];
返回newObj;
}, {})
);
const result=removeZero({a:0,b:1,c:-1});

控制台日志(结果)多亏了T.J,我找到了这个解决方案:

const removeZero = (item) => (
    Object
      .keys(item)
      .filter(Boolean)
      .map((key) => ({ [key]: item[key] }))
      .reduce((acc, curr) => ({ ...acc, ...curr }))
  )

多亏了T.J,我找到了这个解决方案:

const removeZero = (item) => (
    Object
      .keys(item)
      .filter(Boolean)
      .map((key) => ({ [key]: item[key] }))
      .reduce((acc, curr) => ({ ...acc, ...curr }))
  )
您不需要中间
.filter
.map
步骤。他们读得稍微好一点,但在这个过程中增加了很多不必要的迭代。您可以将函数编写为单个reduce

const removeZero=o=>
对象。键(o)
.减少((acc,k)=>{
如果(o[k]==0)
返回acc
其他的
返回Object.assign(acc,{[k]:o[k]})
}, {})
让output=removeZero({a:0,b:1,c:-1})
console.log(输出)
您不需要中间的
.filter
.map
步骤。他们读得稍微好一点,但在这个过程中增加了很多不必要的迭代。您可以将函数编写为单个reduce

const removeZero=o=>
对象。键(o)
.减少((acc,k)=>{
如果(o[k]==0)
返回acc
其他的
返回Object.assign(acc,{[k]:o[k]})
}, {})
让output=removeZero({a:0,b:1,c:-1})


console.log(output)
因此,如果这是功能性的,那么您不会删除属性,而是创建一个只包含您想要保留的属性的新对象,对吗?@t.J.Crowder是的。您是正确的
reduce
创建一个新对象您正在将
.filter(Boolean)
应用于属性名称,而不是值。此外,您的方法会生成相当多的中间对象。简单for循环或forEach可能“更便宜”(或者T.J.做过的;)),因此,如果这是功能性的,那么您不会删除属性,而是创建一个新对象,只保留您想要保留的属性,对吗?@T.J.Crowder是的。您是正确的
reduce
创建一个新对象您正在将
.filter(Boolean)
应用于属性名称,而不是值。此外,您的方法会生成相当多的中间对象。一个简单的for循环或forEach可能会“更便宜”(或者T.J.所做的;)),这至少避免了所有中间对象。美好的回答得好,TJ。您还可以使用
Object.assign(newObj,{[key]:item[key]})
,这避免了命令式赋值和对象扩展语法的需要。^^@T.J.Crowder抱歉,这不是命令式风格。我的意思是,我们很幸运,
Object.assign
在这里提供了我们需要的返回值,这(我认为)使它成为一个好的选择fit@naomik:未将其视为批评。:-)(我希望你能提出有用的批评,无论如何都会得到感激。)这至少避免了所有的中间目标。美好的回答得好,TJ。您还可以使用
Object.assign(newObj,{[key]:item[key]})
,这避免了命令式赋值和对象扩展语法的需要。^^@T.J.Crowder抱歉,这不是命令式风格。我的意思是,我们很幸运,
Object.assign
在这里提供了我们需要的返回值,这(我认为)使它成为一个好的选择fit@naomik:未将其视为批评。:-)(在任何情况下,我都会感激您提出的有用的批评意见。)请注意,您的过滤器并没有按照您的问题陈述中所说的做。它将删除所有具有falsy值的属性,而不是值为0的属性。(另请参见我在我的答案中添加的第二个选项,就在您发布此内容之前,如果您不需要它,您不需要
setProp
。)请注意,您的过滤器并没有按照您的问题陈述所说的做。它将删除所有具有falsy值的属性,而不是值为0的属性。(另请参见我在我的答案中添加的第二个选项,就在您发布此内容之前,如果您不需要,您不需要
setProp
。)