The task is as follows:

var streak = { min: '', max: '', length: '', series: [] } var allStreaks = [] 

I have an array of numbers:

 var arr = [19, 20, 21, 22, 17, 18, 19, 7, 8, 9] 

I need to distribute them across arrays so that these numbers are in it in ascending order, and write it all in this format:

 [{ min: 19, max: 22, length: 4, series: [19, 20, 21, 22] }, { min: 17, max: 19, length: 3, series: [17, 18, 19] }, { min: 7, max: 9, length: 3, series: [7, 8, 9] }] 

In the original array, the numbers go in the order in which I need them (as if these numbers went on dates - one number - one day) I need to catch how many "days" these numbers increased, from what date it started and on which it stopped and then all over again. The first 4 numbers of the arr array (19 20 21 22) should create an object in which the minimum number (19) will be written, the maximum number (22), how many total numbers were written (4) and the array of these numbers itself [19, 20, 21 , 22]. Likewise, with the second incremental streak from 17 to 19, etc. The numbers in the source array are absolutely random and you need to track this sequence of increases and as soon as you find a number less than the previous one, start a new array.

Currently doing this:

 for (var i = 0; i < arr.length-1; i++) { if (arr[i] < arr[i+1]) { streak.series.push(arr[i]) } else { streak.series.push(arr[i]) //Сохранит последний элемент первого стрика break; } } 

So I successfully get the first streak, but if I need to continue, then difficulties arise:

 for (var i = 0; i < arr.length-1; i++) { if (arr[i] < arr[i+1]) { streak.series.push(arr[i]) } else if ((arr[i] > arr[i-1]) && (arr[i] > arr[i+1])) { streak.series.push(arr[i]) // Это ловит и записывает последний элемент первого стрика, получается steak.series = [19,20,21,22] // но он на этом не останавливается и продолжает записывать все числа исходного массива // так как они потом подходят под первый if (arr[i] < arr[i+1]) // и в результате у меня просто переписывается весь исходный массив } else {continue;} } 
  • how to handle equality of elements? - splash58
  • one
    How do you even distribute them? - Mihanik71
  • At first I tried to distribute with a simple condition if (arr [i] <arr [i + 1]) {allStreaks.push (arr [i])}, but then I can’t catch the last element if I do a check in the style else if (((arr [i]> arr [i-1]) && (arr [i]> arr [i + 1])) {allStreaks.push (arr [i])} then it inserts all the numbers into one arry at once - Ivan
  • You are hinted that the distribution logic is incomprehensible. why from one array it turns out as many as three ..... I would personally understand if you are sorting in every ten (0-9, 10-19, 20-29, etc.) ... but you number 19 and in the first object of the total array and in the second - Alexey Shimansky
  • In the original array, the numbers go in the order in which I need them (as if these numbers went on dates - one number - one day) I need to catch how many "days" these numbers increased, from what date it started and on which it stopped and then all over again. The first 4 numbers of the arr array (19 20 21 22) should create an object in which the minimum number (19) will be written, the maximum number (22), how many total numbers were written (4) and the array of these numbers itself [19, 20, 21 , 22]. Similarly, with the second rising streak from 17 to 19, etc. - Ivan

4 answers 4

  var arr = [19, 20, 21, 22, 17, 18, 19, 7, 8, 9] var resArr = []; var min = max = length = 0; var tempArr = []; var prev = 0; arr.forEach(function(item) { if(prev > item && prev){ resArr.push({'min':min,'max':max,'length':length, 'series':tempArr}); min = 0; max = 0; tempArr = []; length = 0; } if(item > max) max = item; if(item < min || min == 0) min = item; length++; tempArr.push(item); prev = item; }); resArr.push({'min':min,'max':max,'length':length, 'series':tempArr}); console.log(resArr); 

  • Yes!! Thank you very much, puzzled for a long time - Ivan
  • @Ivan IMHO there are a lot of unnecessary checks and installations if, then, and if so, then when one is enough ... and temporary variables with arrays are also odd ..... but this is my opinion - Alexey Shimansky
  • @ Alexey Shimansky You want to say that 3 conditions are worse than 3 cycles? - Mihanik71

 var allStreaks = []; var arr = [19, 20, 21, 22, 17, 18, 19, 7, 8, 9]; var prevMaxPos = 0; doWork(); console.log(allStreaks); // функции работы и заноса в итоговый массив function doWork() { for (var i = 1; i < arr.length; ++i) { if (arr[i] < arr[i - 1]) { allStreaks.push(setStreak(arr.slice(prevMaxPos, i))); prevMaxPos = i; } } if (arr.slice(prevMaxPos).length > 0) allStreaks.push(setStreak(arr.slice(prevMaxPos))); } function setStreak(arr) { return streak = { min: arr[0], max: arr[arr.length - 1], length: arr.length, series: arr } } 

  • Thank you very much! It really helped. Also a very good option! Even simpler, I can have more than 500-1000 objects in the source array. So, too, tried to do, began to swear at the Maximum call stack size exceeded - Ivan

solution in the style of minimalism ...

 var arr = [19, 20, 21, 22, 17, 18, 19, 7, 8, 9]; function go(d) { var a; return d.reduce(function(c, b) { a && b == a.max + 1 ? (a.max = b, a.length++, a.series.push(b)) : (a = { min: b, max: b, length: 1, series: [b] }, c.push(a)); return c }, []) }; console.log(go(arr)) 

    another minimalistic but readable solution

     var arr = [19, 20, 21, 22, 17, 18, 19, 7, 8, 9], distribute = function(arr) { var out = [], series = [], i = 1; while (i < arr.length + 1) { series.push( arr[i-1] ); if (! (arr[i-1] < arr[i++])) { out.push({ min: series[0], max: series[series.length-1], length: series.length, series: series.slice() }); series = []; } } return out; } console.log( distribute(arr) );