'How to subtract two array values (from different keys) using a ramda pipe?
In a ramda pipe, I want to subtract the values of two array keys, to ultimately end up with an array of those differences.
For example, consider the following mice_weights array. I want to get an array with the differences weight_post minus weight_pre, for the male mice only.
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
}
]
So based on this answer, I can construct 2 equivalent pipes, get_pre() and 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: https://stackoverflow.com/a/45342187/6105259
console.log(res_diff); // [8, 5]
Although [8, 5] is the expected output, I wonder if there's a shorter way using ramda's pipe such as:
// pseudo-code
const get_diff = R.pipe(
filter_males,
R.subtract("weight_pre", "weight_post")
)
get_diff(mice_weights) // gives [8, 5]
Is it possible to achieve something similar using ramda? Perhaps there's a built-in functionality for such a task?
Solution 1:[1]
Sorry, I don't know about ramda pipes, but this is a trivial matter for array filtering and mapping.
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]
Solution 2:[2]
I would propose to use props and reduceRight functions in order to achieve that:
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));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Kinglish |
| Solution 2 | Konstantin Samarin |
