Home > Software engineering >  how to find elements of a numeric array that are greater than the elements in front of them
how to find elements of a numeric array that are greater than the elements in front of them

Time:02-16

array: const data = [158,164,742,99,155,250,240,87]

It is necessary to output to the console numbers that are greater than the previous ones: console.log(164 742 155 250)

const data = [158, 164, 742, 99, 155, 250, 240, 87]
function biggerElement(data) {
  for (let i = 1; i < -1; i  ) {
    if (data[i] > data[i - 1]) console.log(data[i])
  }
}

how to solve this task? thanks

CodePudding user response:

Use .flatMap() and compare current with future values:

x < a[i 1] ? a[i 1] : []

It has come to my attention that there's very little use for .flatMap() as a filter.

Then why not use .map() since .flatMap() is essentially the same thing but with one extra step? That extra step allows me to think a straight forward logic in which I can use simpler algorithms and not have to worry about the common side affects when dealing with arrays like getting empties. Here's a version of example #1 vs. a version using .map().

const data = [158, 164, 742, 99, 155, 250, 240, 87];

let resA = data.flatMap((x, i, a) => x < a[i   1] ? a[i   1] : []);

console.log(resA);

let resB = data.map((x, i, a) => x < a[i   1] ? a[i   1] : '');

console.log(resB);

So both .map() and .flatMap() are required to return after every iteration, but because .flatMap() has a built-in .flat() method, you can return an empty array which becomes nothing which is better than an empty like '', or undefined.

How about .filter() which of course is the most obvious answer? Compare Vectorjohn's callback, vs. my callback:

i > 0 && x > a[i - 1] // Vectorjohn, using .filter()

x < a[i   1] ? a[i   1] : [] // Me, using .flatMap()

Using .filter() you actually have no need to worry about blowing past zero and returning undefined because .filter() never returns falsey data only truthy data. So his callback can simply be the backwards version of my callback by removing i > 0 &&:

x > a[i - 1] // .filter() will return x

x < a[i   1] ? a[i   1] : [] // .flatMap() will return a[i   1]

My callback doesn't eliminate undefined automatically so amittedly it is more verbose than Vj's callback (once I corrected it). But, .flatMap() can do far more than .filter(). While .filter() always returns the current value (x) on each iteration, .flatMap() can return anything (a[i 1]), multiple anythings (["any", x]), or nothing ([]) on each iteration.

Example 1

const data = [158, 164, 742, 99, 155, 250, 240, 87];

let res = data.flatMap((x, i, a) => x < a[i   1] ? a[i   1] : []);

console.log(res);

CodePudding user response:

The array filter method runs a function for each element in an array, and returns only the elements for which the function returns true. It receives the index of the current element. So you can access the previous element in your filter callback.

data.filter((value, i) => i > 0 && value > data[i - 1])

filter also receives the original array as the third argument, so you could use that instead of accessing data directly if that matters for your case, like if you wanted to make this helper reusable:

const biggerThanPrevious = (value, i, array) => i > 0 && value > array[i - 1]
// ... then somewhere else
const data = [158,164,742,99,155,250,240,87]
console.log(data.filter(biggerThanPrevious))

CodePudding user response:

Just iterate the array. Maybe it's not the shortest or fastest way, but it's one of the most readables.


const data = [158, 164, 742, 99, 155, 250, 240, 87]

let numbers_to_print = ''

data.forEach(number => {
  const index = data.indexOf(number)

  if (number > data[index - 1]) {
    numbers_to_print  = `${number} `
    // you can also just console.log(number), but I like to use a string
  } 
})

console.log(numbers_to_print)

CodePudding user response:

You almost had it with your forloop.

NOTE: Never use a minus or negative value in your loops unless the conditions requires you iterating your loop backwards.

const data = [158, 164, 742, 99, 155, 250, 240, 87];
var result = [];
for(let i = 0; i < data.length; i  ){
  if(data[i] > data[i - 1]){
    result.push(data[i]);
  }
}

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

CodePudding user response:

Sounds like a good application for Array.prototype.reduce().

Let the 2nd parameter of the reduce function (the accumulator/carry value) be an object with two keys representing the resulting array and the previous iteration's value.

let data = [158, 164, 742, 99, 155, 250, 240, 87];

let result = data.reduce(function(accumulator, currValue) {
  if (currValue > accumulator.lastValue) {
    accumulator.greaterThanPrev.push(currValue);
  }
  accumulator.lastValue = currValue;
  return accumulator;

}, {
  greaterThanPrev: [],
  lastValue: 4294967295 // BACK-COMPAT. MAX INT.
});

console.log(result.greaterThanPrev)

Then for each iteration, test the current iteration's value against the 'lastValue' in the object being passed through the iterations of the reduce function. If it's greater, push it onto the 'greaterThanPrev' array and update the 'lastValue' key-value. Then return that object for the next iteration to work against. When the reduce function is done, it will return the ending object and the 'greaterThanPrev' will contain all of the desired values.

I'm certain someone else could think of a cleaner approach, but this came to mind rather quickly.

  • Related