简体   繁体   中英

Find consecutive numbers in multiples arrays JavaScript

I have array structured like this:

[
    [8,[1]],
    [15,[2]],
    [20,[3]],
    [23,[4,41]],
    [497,[18]],
    [1335,[38]],
    [2092,[39,55,61]],
    [3615,[5]],
    [4121,[14]],
    [5706,[39,55,61]],
    [5711,[62]],
    [5714,[63]],
    [5719,[64]],
    [6364,[38]]
]

I use the modified code from this answer to find consecutive numbers but I can't adapt it to also find consecutive numbers from arrays with multiple values

This is my code :

const a = [
    [8,[1]],
    [15,[2]],
    [20,[3]],
    [23,[4,41]],
    [497,[18]],
    [1335,[38]],
    [2092,[39,55,61]],
    [3615,[5]],
    [4121,[14]],
    [5706,[39,55,61]],
    [5711,[62]],
    [5714,[63]],
    [5719,[64]],
    [6364,[38]]
];

// this variable will contain arrays
let finalArray = [];
// Create a recursive function
function checkPrevNextNumRec(array) {
  let tempArr = [];
  // if the array contaon only 1 element then push it in finalArray and
  // return it
  if (array.length === 1) {
    finalArray.push(array);
    return
  }
  // otherside check the difference between current & previous number
  for (let i = 1; i < array.length; i++) {
    if (array[i][1][0] - array[i - 1][1][0] === 1) {
      // if current & previous number is 1,0 respectively 
      // then 0 will be pushed
      tempArr.push(array[i - 1]);
    } else {
      // if current & previous number is 5,2 respectively 
      // then 2 will be pushed
      tempArr.push(array[i - 1])
      // create a an array and recall the same function
      // example from [0, 1, 2, 5, 6, 9] after removing 0,1,2 it 
      // will create a new array [5,6,9]
      let newArr = array.splice(i);
      finalArray.push(tempArr);
      checkPrevNextNumRec(newArr)
    }
    // for last element if it is not consecutive of
    // previous number 
    if (i === array.length - 1) {
      tempArr.push(array[i]);
      finalArray.push(tempArr)
    }
  }
  }
checkPrevNextNumRec(a)

And here the result, as you can see, all the tables containing consecutive figures in [i][1][0] have been grouped

[
    [
        [8,[1]],
        [15,[2]],
        [20,[3]],
        [23,[4,41]]
    ],
    [
        [497,[18]]
    ],
    [
        [1335,[38]],
        [2092, [39,55,61]]
    ],
    [
        [3615,[5]]
    ],
    [
        [4121,[14]]
    ],
    [
        [5706,[39,55,61]]
    ],
    [
        [5711,[62]],
        [5714,[63]],
        [5719,[64]]
    ],
    [
        [6364,[38]]
    ]
]

But I need that field 5706 is also included with 5711, 5714, and 5719, but obviously it is not included because is not in [i][1][0] I thought of being inspired by this post but I cannot integrate it correctly

Can you help me?

Thanks!

You need to check the last element of the grouped value.

 const array = [[8, [1]], [15, [2]], [20, [3]], [23, [4, 41]], [497, [18]], [1335, [38]], [2092, [39, 55, 61]], [3615, [5]], [4121, [14]], [5706, [39, 55, 61]], [5711, [62]], [5714, [63]], [5719, [64]], [6364, [38]]], grouped = array.reduce((r, a) => { var last = r[r.length - 1]; if (!last || last[last.length - 1][1][0] + 1 !== a[1][0]) r.push(last = []); last.push(a); return r; }, []); console.log(grouped);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

Basically the logic here is to iterate over the input and at each iteration, compare it with the data values from the previous iteration ie: prevData .

On each iteration, I used Array.prototype.map to create a new array that contains the what-would-be consecutive values (relative to the data in the previous iteration) by simply adding 1 to each item in prevData .

Next step is to loop that array to see if we encounter a consecutive value - as soon as we do we can break as there's no need to keep checking.

Finally is we apply the grouping logic with a single if/else .

 const a = [ [8, [1]], [15, [2]], [20, [3]], [23, [4, 41]], [497, [18]], [1335, [38]], [2092, [39, 55, 61]], [3615, [5]], [4121, [14]], [5706, [39, 55, 61]], [5711, [62]], [5714, [63]], [5719, [64]], [6364, [38]] ]; function group(input) { let prev; return input.reduce((accum, el) => { let hasConsecutive = false; const [key, current] = el; if (prev == null) { prev = current; } const consecutives = prev.map(n => n + 1); for (let i = 0; i < consecutives.length; i += 1) { if (current.includes(consecutives[i])) { hasConsecutive = true; break; } } if (prev && hasConsecutive) { accum[accum.length - 1].push(el); } else { accum.push([el]); } prev = current; return accum; }, []); } console.log(group(a));

Here's the result run through a beautifier:

[
    [
        [8, [1]],
        [15, [2]],
        [20, [3]],
        [23, [4, 41]]
    ],
    [
        [497, [18]]
    ],
    [
        [1335, [38]],
        [2092, [39, 55, 61]]
    ],
    [
        [3615, [5]]
    ],
    [
        [4121, [14]]
    ],
    [
        [5706, [39, 55, 61]],
        [5711, [62]],
        [5714, [63]],
        [5719, [64]]
    ],
    [
        [6364, [38]]
    ]
]

The following code enumerates each of the items in the array.

For each item, its sub-array is enumerated to see if the following item fits in a sequence.

If it fits in sequence, the next item is appended to a temporary variable, and we continue to the next item.

If the last entry in the subarray is reached without detecting a continuation of the sequence, we end the current sequence, start a new sequence and continue to the next item.

 const data = [ [8,[1]], [15,[2]], [20,[3]], [23,[4,41]], [497,[18]], [1335,[38]], [2092,[39,55,61]], [3615,[5]], [4121,[14]], [5706,[39,55,61]], [5711,[62]], [5714,[63]], [5719,[64]], [6364,[38]] ] function sequences(data) { const result = [] let sequence = [data[0]] for(let x=0; x<data.length-1; x++) { const [,sub] = data[x] for(let y=0; y<sub.length; y++) { const currSubV = sub[y] const [,nextSub] = data[x+1] if(nextSub.some((nextSubV) => currSubV+1 === nextSubV)) { sequence.push(data[x+1]) break } if(y === sub.length-1) { result.push(sequence) sequence = [data[x+1]] } } } return result } for(let s of sequences(data)) console.log(JSON.stringify(s).replace(/\\s/g))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM