JavaScript减少了筛选列表

时间:2018-04-05 04:46:49

标签: javascript

我想要过滤一个对象数组,然后将其中一个属性缩减为累加器。

编辑到底我想要的是一个数字。

我可以分两步这样做:

<div>Standalone:</div>
<svg xmlns="http://www.w3.org/2000/svg" width="75" height="50" style="position:relative"><circle cx="25" cy="25" r="25" fill="red" /><foreignObject width="100%" height="100%"><html xmlns="http://www.w3.org/1999/xhtml"><style>.x {position: absolute;background: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'100'%20height%3D'50'%3E%3Ccircle%20cx%3D'50'%20cy%3D'25'%20r%3D'25'%20fill%3D'blue'%2F%3E%3C%2Fsvg%3E"); width: 100%; height: 100%;}</style><div class="x"></div></html></foreignObject></svg>

<div>As image source:</div>
<img style="position:relative" src="data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2275%22%20height%3D%2250%22%20style%3D%22position%3Arelative%22%3E%3Ccircle%20cx%3D%2225%22%20cy%3D%2225%22%20r%3D%2225%22%20fill%3D%22red%22%20%2F%3E%3CforeignObject%20width%3D%22100%%22%20height%3D%22100%%22%3E%3Chtml%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%3E%3Cstyle%3E.x%20%7Bposition%3A%20absolute%3Bbackground%3A%20url(%22data%3Aimage%2Fsvg%2Bxml%3Butf8%2C%253Csvg%2520xmlns%253D'http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg'%2520width%253D'100'%2520height%253D'50'%253E%253Ccircle%2520cx%253D'50'%2520cy%253D'25'%2520r%253D'25'%2520fill%253D'blue'%252F%253E%253C%252Fsvg%253E%22)%3B%20width%3A%20100%25%3B%20height%3A%20100%25%3B%7D%3C%2Fstyle%3E%3Cdiv%20class%3D%22x%22%3E%3C%2Fdiv%3E%3C%2Fhtml%3E%3C%2FforeignObject%3E%3C%2Fsvg%3E">

但是我很熟悉和ES6&#39;所以我想在一行中做到这一点。

帮我堆栈溢出,如何组合过滤器并减少?

编辑:,我已经尝试过这条记录:

let filteredList = list.filter( item => item.topLevel )
return filteredList.reduce( (a, i) => a + i.stock ), 0)

它似乎正在返回一个数组。我有什么不对的吗?

编辑:我被要求显示所需的输入和输出:

    product_variations.filter( pv => pv.topLevel )
            .reduce((a, fpv) => a + fpv.stock) , 0)

2 个答案:

答案 0 :(得分:1)

您的代码中有一个错位的右括号。删除它将解决它:

const productVariations = [{
  topLevel: true,
  stock: 1
}, {
  topLevel: false,
  stock: 2
}];

const result = productVariations.filter(pv => pv.topLevel)
                                .reduce((a, fpv) => a + fpv.stock, 0);
                                
console.log(result);

答案 1 :(得分:1)

毫无疑问在一行中执行此操作,链接filterreduce调用会导致列表的多次迭代 - 执行一次迭代是聪明的事情

list.reduce
  ( (acc, item) =>
      Boolean (item.topLevel)
        ? acc + item.stock
        : acc
  , 0
  )

您是否知道filter可以用reduce编写?

&#13;
&#13;
const filter = (f, xs) =>
  xs.reduce
    ( (acc, x) =>
        f (x)
          ? [ ...acc, x ]
          : acc
    , []
    )

console.log (filter (x => x > 3, [ 1, 2, 3, 4, 5 ]))
// [ 4, 5 ]
&#13;
&#13;
&#13;

因此,当您撰写list.filter(...).reduce(...)时,我们可以将其视为减少的序列。您是否知道这种减少的顺序可以推广?下面我们介绍一种叫做传感器的东西,它提供了一种方法来对许多减少步骤进行排序,但只触摸基础数据一次 - 无论你在序列中添加了多少减少步骤

&#13;
&#13;
const identity = x =>
  x

const add = (x, y) =>
  x + y
    
const tfilter = f => concat =>
  (acc, x) => f (x) ? concat (acc, x) : acc
  
const tmap = f => concat =>
  (acc, x) => concat (acc, f (x)) 
  
const comp = (f, g) =>
  x => f (g (x))
  
const transduce = (...ts) => (f, init, xs) =>
  xs.reduce
    ( ts.reduce (comp, identity) (f)
    , init
    )
  
const main =
  transduce
    ( tfilter (x => x.topLevel)
    , tmap (x => x.stock)
    )
    
const data =
  [ { topLevel: true, stock: 1 }
  , { topLevel: false, stock: 10 }
  , { topLevel: true, stock: 1 }
  , { topLevel: true, stock: 1 }
  ]

console.log (main (add, 0, data))
// 3
&#13;
&#13;
&#13;

如果您对传感器感兴趣,它们对于解决一些整洁的问题非常有用。我已经写了更多here