如何使我的JS解决方案正常运行?

时间:2018-05-18 21:09:42

标签: javascript arrays angular function functional-programming

我有一些来自Angular的优雅服务的数据看起来像这样(简要):

const obj = {
  field: [
    {
      id: 1,
      items: []
    },
    {
      id: 2,
      items: [ { wateva: 'wateva1' } ]
    },
    {
      id: 3,
      items: false
    },
    {
      id: 4,
      items: [ { yeah: 7 } ]
    }
  ] 
}

好吧,我的任务就是收集所有非空的数组项。 我的解决方案(实际上我的解决方案是用TypeScript和Angular 5编写的,但是为了使它更简单易懂,它将会像......):

function getItems() {
  const items = [];

  obj.field.forEach(currentField => {
    if (currentField.items && currentField.items.length) {
      currentField.items.forEach(currentItem => items.push(currentItem));
    }
  });

  return items;
}

是的,它很简单,它按预期工作(当前的一个将返回......):

[ { wateva: 'wateva1' }, { yeah: 7 } ]

现在我的问题......如何使我的解决方案正常运行?我想摆脱我的新变量 items ,我不想推入那个变量,我只想在一个动作中返回结果。任何帮助将不胜感激。

P.S。不接受第3个图书馆的建议:)

4 个答案:

答案 0 :(得分:2)

如果你可以使用es6(因为你提到你正在使用打字稿,那应该没问题),你可以通过组合concatmap将其变成一个很好的功能性单行程, filter和传播运营商:

const obj = {
  field: [
    {
      id: 1,
      items: []
    },
    {
      id: 2,
      items: [ { wateva: 'wateva1' } ]
    },
    {
      id: 3,
      items: false
    },
    {
      id: 4,
      items: [ { yeah: 7 } ]
    }
  ] 
}

function getItems(obj) {
  return [].concat(...obj.field.map(o => o.items).filter(Array.isArray))
}

console.log(getItems(obj))

答案 1 :(得分:1)

您可以使用flatMap (stage 3)flatMap符合Fantasy Land的chain规范。

data.field.flatMap
  (({ items }) =>
    Array.isArray (items) ? items : []
  )

// [ { wateva: 'wateva1' }, { yeah: 7 } ]

您可以在没有它的环境中对其进行填充

Array.prototype.flatMap = function (f) {
  return this.reduce
    ( (acc, x) =>
        acc.concat (f (x))
    , []
    )
}

完整的程序演示



Array.prototype.flatMap = function (f) {
  return this.reduce
    ( (acc, x) =>
        acc.concat (f (x))
    , []
    )
}

const data = 
  { field:
    [ { id: 1, items: [] }
    , { id: 2, items: [ { wateva: 'wateva1' } ] }
    , { id: 3, items: false }
    , { id: 4, items: [ { yeah: 7 } ] } 
    ]
  }

const result =
  data.field.flatMap
    (({ items }) =>
      Array.isArray (items) ? items : []
    )

console.log (result)
// [ { wateva: 'wateva1' }, { yeah: 7 } ]




答案 2 :(得分:0)

您可以使用Array.reduce和spread运算符累积到空数组:

obj.field.reduce(
    (acc, current) => current.items && current.items.length > 0 ? [...acc, ...current.items] : acc, [])
);

答案 3 :(得分:0)

使用Array.prototype.reduceobject destructuring, and spread assignments

function getItems({ field }) {
    return field.reduce((result, { items }) => 
        items instanceof Array ? 
        items.reduce((items, item) => [...items, item], result) :
        result
    , []);
}