如何使用 ramda 管道减去两个数组值(来自不同的键)?

How to subtract two array values (from different keys) using a ramda pipe?

ramda pipe 中,我想减去两个数组键的值,最终得到这些差异的数组。

例如,考虑以下 mice_weights 数组。我想得到一个差值 weight_post 减去 weight_pre 的数组,仅适用于雄性小鼠。

const mice_weights = [
    {
        "id": "a",
        "weight_pre": 20,
        "weight_post": 12,
        "is_male": true
    },
    {
        "id": "b",
        "weight_pre": 25,
        "weight_post": 19,
        "is_male": false
    },
    {
        "id": "c",
        "weight_pre": 15,
        "weight_post": 10,
        "is_male": true
    },
    {
        "id": "d",
        "weight_pre": 30,
        "weight_post": 21,
        "is_male": false
    }
]

所以基于,我可以构造2个等价的管道,get_pre()get_post():

const R = require("ramda");

filter_males = R.filter(R.path(["is_male"])) // my filtering function

const get_pre = R.pipe(
    filter_males,
    R.map(R.prop("weight_pre"))
)

const get_post = R.pipe(
    filter_males,
    R.map(R.prop("weight_post"))
)

res_pre  = get_pre(mice_weights) // [20, 15]
res_post = get_post(mice_weights) // [12, 10]


const res_diff = res_pre.map((item, index) => item - res_post[index]) // taken from: 

console.log(res_diff); // [8, 5]

虽然 [8, 5] 预期的输出,但我想知道是否有更短的方法使用 ramda 的管道,例如:

// pseudo-code

const get_diff = R.pipe(
    filter_males,
    R.subtract("weight_pre", "weight_post")
)

get_diff(mice_weights) // gives [8, 5]

是否可以使用 ramda 实现类似的功能?也许有针对此类任务的内置功能?

抱歉,我不知道 ramda 管道,但这对于数组过滤和映射来说是一件小事。

const get_diff = (n, v) => // this takes a field and value to filter
       mice_weights 
       .filter(f => f[n] === v) // this keeps only datasets that have the field/value combo you're seeking
       .map(f => f.weight_pre - f.weight_post) // this gets the diff

const mice_weights = [{
    "id": "a",
    "weight_pre": 20,
    "weight_post": 12,
    "is_male": true
  },
  {
    "id": "b",
    "weight_pre": 25,
    "weight_post": 19,
    "is_male": false
  },
  {
    "id": "c",
    "weight_pre": 15,
    "weight_post": 10,
    "is_male": true
  },
  {
    "id": "d",
    "weight_pre": 30,
    "weight_post": 21,
    "is_male": false
  }
]

const get_diff = (n, v) => mice_weights.filter(f => f[n] === v).map(f => f.weight_pre - f.weight_post)

console.log(get_diff('is_male', true)) // gives [8, 5]

我建议使用 propsreduceRight 函数来实现:

const getProps = R.props(['weight_pre', 'weight_post'])

const subtract = R.reduceRight(R.subtract)(0)

const get_diff = R.pipe(
    R.filter(R.path(['is_male'])),
    R.map(R.pipe(getProps, subtract))
)

console.log(get_diff(mice_weights));

要在单个对象中获得权重差异,请使用 R.pipe 创建一个函数,该函数使用 R.props 获取相关道具值,并将它们应用于 R.subtract

现在您可以创建一个函数来过滤项目,并使用权重计算函数映射对象:

const { pipe, props, apply, subtract, filter, prop, map,  } = R

const calcWeightDiff = pipe(
  props(['weight_pre', 'weight_post']), 
  apply(subtract)
)

const fn = pipe(
  filter(prop('is_male')),
  map(calcWeightDiff)
)

const mice_weights = [{"id":"a","weight_pre":20,"weight_post":12,"is_male":true},{"id":"b","weight_pre":25,"weight_post":19,"is_male":false},{"id":"c","weight_pre":15,"weight_post":10,"is_male":true},{"id":"d","weight_pre":30,"weight_post":21,"is_male":false}]

const result = fn(mice_weights)

console.log(result) // gives [8, 5]
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>