-1

I have an array like this from which I am trying to filter out values.

The array is like this:

const arr = [
  {
    date: "2020-05-18",
    values: [
      { name: "a", value: 1 },
      { name: "b", value: 2 }
    ]
  },
  {
    date: "2020-05-19",
    values: [
      { name: "a", value: 3 },
      { name: "b", value: 8 }
    ]
  },
  {
    date: "2020-05-20",
    values: [
      { name: "a", value: 5 },
      { name: "b", value: 6 }
    ]
  }
]

The code is just a function which takes name as an argument and returns the result below.

Code

const result = (name) => {
    //return the below result
}

result("b");  //any name could be passed

Result

[
  { date: "2020-05-18", value: 2 },
  { date: "2020-05-19", value: 2 },
  { date: "2020-05-20", value: 6 }
]

How can this be achieved in JS? It would be better, if the output could be achieved using ramda.js

Thanks

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
newbie
  • 530
  • 1
  • 9
  • 36
  • And the problem is? `Array.prototype.filter()` + `Array.prototype.map()` or `Array.prototype.reduce()` or just a plain old `for` – Andreas Jun 24 '20 at 17:01
  • could you post your codes you already tried? Anyway, one nested for-loop or nested forEach can reach the goal. – Sphinx Jun 24 '20 at 17:02
  • None of the [ES6 additions to `Array`](https://kangax.github.io/compat-table/es6/#test-Array.prototype_methods) would help – Andreas Jun 24 '20 at 17:05
  • @Sphinx I am on it and couldn't achieve it properly. That is why asked for help – newbie Jun 24 '20 at 17:08

3 Answers3

1

Uses nested for-loop or nested forEach will reach the goal.

Below is one sample for nested forEach:

const arr = [
  {
    date: "2020-05-18",
    values: [
      { name: "a", value: 1 },
      { name: "b", value: 2 }
    ]
  },
  {
    date: "2020-05-19",
    values: [
      { name: "a", value: 3 },
      { name: "b", value: 8 }
    ]
  },
  {
    date: "2020-05-20",
    values: [
      { name: "a", value: 5 },
      { name: "b", value: 6 }
    ]
  }
]
function filter(arr, name) {
  let result = []
  arr.forEach(item => item.values.forEach(sub => {
    if (sub.name === name) result.push({'date': item.date, 'value': sub.value})
  }))
  return result
}
console.log(filter(arr, 'b'))
Sphinx
  • 10,519
  • 2
  • 27
  • 45
0

check this code.I hope it helps you

const result = (name) => {
    return arr.map((item)=> {
      var i = item.values.findIndex(el=> el.name == name)
      if(i > -1 ) {
        return { date: item.date , value : item.values[i].value }
      } else {
        return null;
      }
    }).filter(item => item !== null )
}
Ehsan Nazeri
  • 771
  • 1
  • 6
  • 10
0

There are simpler alternatives to ramda.

const arr = [
  { date: "2020-05-18", values: [ { name: "a", value: 1 }, { name: "b", value: 2 } ] },
  { date: "2020-05-19", values: [ { name: "a", value: 3 }, { name: "b", value: 8 } ] },
  { date: "2020-05-20", values: [ { name: "a", value: 5 }, { name: "b", value: 6 } ] }
]

const { pipe, fork, map, get } = rubico

const find = f => x => x.find(f)

const main = name => map(fork({
  date: get('date'),
  value: pipe([
    get('values'),
    find(obj => obj.name === name),
    get('value'),
  ]),
}))

console.log(
  main('b')(arr),
)
<script src="https://unpkg.com/rubico"></script>

Disclaimer: I'm the author of rubico.

Documentation

richytong
  • 2,387
  • 1
  • 10
  • 21
  • Its very complex for newbies like me. Just a suggestion :) – newbie Jun 24 '20 at 18:15
  • 1
    I understand it's a bit much to wrap your head around at first. I wrote an [article on functional programming](https://dev.to/richytong/practical-functional-programming-in-javascript-data-last-1gjo) that may help your understanding. – richytong Jun 24 '20 at 18:17
  • 1
    I ll give it a read. Thanks – newbie Jun 24 '20 at 18:21