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

时间:2016-12-16 14:37:57

标签: javascript arrays functional-programming

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

output:

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

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

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

知道如何解决这个问题吗?

3 个答案:

答案 0 :(得分:3)

你非常接近。这很有用,而且大部分都是功能性的(我认为;我完全没有沉浸在函数式编程的习语中),但是除非使用Object.defineProperty来定义属性,否则我认为你必须要对它进行必要的操作。最后一步(设置道具):

const removeZero = item => (
    Object
      .keys(item)
      .filter(key => item[key] !== 0)
      .reduce((newObj, key) => {
        newObj[key] = item[key];
        return newObj;
      }, {})
  );
const result = removeZero({ a: 0, b: 1, c: -1 });
console.log(result);

我想我们每次都可以在reduce创建一个新对象,但这看起来很浪费:

const removeZero = item => (
    Object
      .keys(item)
      .filter(key => item[key] !== 0)
      .reduce((newObj, key) => ({
        ...newObj, [key]: item[key]
      }), {})
  );
const result = removeZero({ a: 0, b: 1, c: -1 });
console.log(result);

...但请注意,这依赖于对象扩展符号,这是第3阶段proposal(可能在ES2018中)但尚未在规范中。

naomik指出我们可以避免做

newObj[key] = item[key];
return newObj;

部分没有使用Object.assign创建新对象,如下所示:

const removeZero = item => (
    Object
      .keys(item)
      .filter(key => item[key] !== 0)
      .reduce((newObj, key) => Object.assign(newObj, {[key]: item[key]}), {})
  );
const result = removeZero({ a: 0, b: 1, c: -1 });
console.log(result);

我会把它留给比我更有用的头脑是否比设置属性和做return的功能更强大。 : - )

答案 1 :(得分:1)

您不需要需要中间.filter.map步骤。他们读得更好但在这个过程中添加了许多不必要的迭代。您可以将您的函数编写为单个reduce

const removeZero = o =>
  Object.keys(o)
    .reduce((acc, k) => {
      if (o[k] === 0)
        return acc
      else
        return Object.assign(acc, { [k]: o[k] })
    }, {})

let output = removeZero({ a: 0, b: 1, c: -1 })
console.log(output)

或者,如果您喜欢@ TJCrowder的方法,但想要避开命令性分配或传播对象提议,则可以使用Object.assign表达式

const removeZero = o =>
  Object.keys(o)
    .filter(k => o[k] !== 0)
    .reduce((acc, k) =>
      Object.assign(acc, { [k]: o[k] }), {})

let output = removeZero({ a: 0, b: 1, c: -1 })
console.log(output)

答案 2 :(得分:0)

感谢T.J我已经达成了这个解决方案:

const setProp = (item, key) => ({[key]: item[key]})

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