how to return the first element of an array given an evaluation condition in Javascript?

Viewed 97

I have two lists and I and need to return only the first number of the tuples in odd position in which sum of the tuples is greater than 70. Example Tuples: [[2,70],[3,71],[4,72],[5,73]] return [[3],[5]]

I seem to be correct in the evaluation of the first part (sum the tuple, greater than 70 and get the odd position) but cant make it return the first element of it. Can you guys help me?

const range = (from, to) => {
  let arr = [];
  for (let i = from; i <= to; i++){
    arr.push(i);
  }
  return arr
}
const ternary = fn => (a, b) => fn(a, b) ? a : b
const not = (fn) => (...args) => !fn(...args)
const greaterThan = num1 => num2 => num1 > num2 ? true : false 
const longestList = (arr1, arr2) => arr1.length>arr2.length ? arr1 : arr2
const tupla = (a,b) => [a,b]
const esImpar = num => num % 2 !== 0 


const zipped = (list1, list2) => {
  return ternary(not(longestList))(range(1,50),range(51,80))
    .map((element, index)=>{
      return tupla(list1[index],list2[index])
      /* return element */
    }) 
}



//tuples in odd position that 
const newArray = zipped(range(1,50),range(51,80)) 
  .map((element, index)=>{
  return element[0] + element[1]  // return sum of the elements of the array
})
  .filter(not(greaterThan(70))) // filters greater than 70
  .filter((element, index)=>{ // filters odd elements
  return esImpar(index) 
})

console.log(newArray)

2 Answers

You are indeed close, but you need to change the order of your chained array methods a little bit, and you should change your filter for numbers under 70 so that it calculates the sum inline. That way you still have access to the original elements after the filter has run.

So for example, the steps should rather be:

  • Filter out even elements.
  • Filter out elements whos sum is under 70.
  • Map each item to get the first element.

To that end, you could modify your snippet like so:

const range = (from, to) => {
  let arr = [];
  for (let i = from; i <= to; i++){
    arr.push(i);
  }
  return arr
}

const ternary = fn => (a, b) => fn(a, b) ? a : b
const not = (fn) => (...args) => !fn(...args)
const greaterThan = num1 => num2 => num1 > num2 ? true : false 
const longestList = (arr1, arr2) => arr1.length>arr2.length ? arr1 : arr2
const tupla = (a,b) => [a,b]
const esImpar = num => num % 2 !== 0 


const zipped = (list1, list2) => {
  return ternary(not(longestList))(range(1,50),range(51,80))
    .map((element, index)=>{
      return tupla(list1[index],list2[index])
      /* return element */
    }) 
}

// Replacing input with your test case: 
const newArray = [[2,70],[3,71],[4,72],[5,73]] 
  // This map will not help you, it destroys the information about specific elements.
  // .map((element, index)=>{ return element[0] + element[1] })
  
  // This is good, but needs to calculate the sum inline!
  // My inline calculation looks complicated, but its not that bad.
  // You can clean it up if you like.
  .filter(item => not(greaterThan(70))(item.reduce((a, b) => a + b, 0))) // filters greater than 70
  
  // Good as is.
  .filter((element, index) => { return esImpar(index) })
  
  // Finally, just map each item to an array containing only the first element:
  .map(element => [element[0]])

console.log(newArray)


Or, as a shorter snippet, the same:

// [[2,70],[3,71],[4,72],[5,73]] return [[3],[5]]
const input_array = [[2,70],[3,71],[4,72],[5,73]];

const result_array = input_array
  .filter((_, i) => i % 2 === 1) // Filter out even indices
  .filter(item => item.reduce((a, b) => a + b, 0) >= 70) // Filter items who's sum is under 70.
  .map(item => [item[0]]) // Map items to get first element.
  
console.log(result_array);

Here you are (starting from your input):

[[2,70],[3,71],[4,72],[5,73]]
     .filter((_,i) => i%2) // only the ones in the odd posiitons
     .filter(el => el[0] + el[1] >= 70) // only the ones with the sum of the two elements greater than 70
     .map(el => [el[0]]) // map to an array of arrays with the first element only

Related