How do I return a group of sequential numbers that might exist in an array?
Assuming it is presorted, you can easily test for a straight like so:
array.each_cons(2).all? { |x,y| y == x - 1 }
To be safe you may want to add the sort:
array.sort.each_cons(2).all? { |x,y| y == x + 1 }
But if you really need to extract the largest sequence, it will take another solution.
Find groups of consecutive numbers inside an array
It's working correctly now. I wish there was some way I could let you know.
This is pretty robust; it will count the occurrences of multiple sequences if they occur more than once. The Map
actually records all sequences but only prints out those that occur more than once.
Note that the second for loop initializes ii
to i
and not 0
.
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
public class Sequences {
public static void main(String [] args) {
int[] arr = {2, 9, 0, 6, 1, 2, 3, 6, 6, 1, 0, 1, 2, 3, 5, 4, 0, 3, 7, 1, 2, 3, 7, 5, 0};
int sequenceLength = 3;
Map<String, Integer> map = new HashMap<String, Integer>();
int count;
String str1, str2;
for (int i = 0; i <= arr.length - sequenceLength; i++) {
str1 = "";
count = 0;
for (int a = i; a < i + sequenceLength; a++) {
str1 += "" + arr[a];
}
if (map.get(str1) != null) {
continue;
} else {
map.put(str1, count);
}
for (int ii = i; ii <= arr.length - sequenceLength; ii++) {
str2 = "";
for (int a = ii; a < ii + sequenceLength; a++) {
str2 += "" + arr[a];
}
if (str1.equals(str2)) {
count++;
map.put(str1, count);
}
}
}
for (Map.Entry<String, Integer> entry : map.entrySet()){
if (entry.getValue() > 1) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
}
}
Grouping consecutive elements together using Javascript
You can use a counter variable which has to be incremented and the difference between the index and the consecutive elements are the same, group them in a temporary array. If the difference is varies for two consecutive array elements, the temporary element has to be moved to the result
and the temporary array has to be assigned a new array object.
var array = [2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 16, 17, 20];
var result = [], temp = [], difference;
for (var i = 0; i < array.length; i += 1) {
if (difference !== (array[i] - i)) {
if (difference !== undefined) {
result.push(temp);
temp = [];
}
difference = array[i] - i;
}
temp.push(array[i]);
}
if (temp.length) {
result.push(temp);
}
console.log(result);
# [ [ 2, 3, 4, 5 ], [ 8, 9 ], [ 12, 13, 14, 15, 16, 17 ], [ 20 ] ]
Group the consecutive numbers from an array with series of numbers which are greater than 2 into subarrays using javascript
You can use a global variable to keep track of the indexes so that it's possible to detect when exists a gap between two numbers, which allows you to add another array. In combination, using ternary operators can make the code cleaner to test for conditions.
const arr = [1, 2, 3, 5, 6, 7, 8, 10, 0, 1, 1, 2, 4, 10, 6, 7, 3];
let lastIdx = -1
const results = arr.reduce((acc, current, idx) =>
(
current > 2 ? (
lastIdx + 1 === idx && acc.length ?
(
lastIdx = idx,
acc[acc.length - 1].push(current),
acc
)
:
(
lastIdx = idx,
[...acc, [current]]
)
) : acc
)
, [])
console.log(results);
Javascript - How Do I Check if 3 Numbers Are Consecutive and Return Starting Points?
It'd be interesting to know the context of this task as well... Anyway, here's my solution:
var arr = [1, 2, 3, 5, 10, 9, 8, 9, 10, 11, 7];
var results = [];
var limit = arr.length - 1;
var sequence = 0;
for (var i = 0; i < limit; ++i) {
var diff = arr[i+1] - arr[i];
if (sequence && sequence === diff) {
results.push(i-1);
continue;
}
sequence = (diff === 1 || diff === -1) // or ... Math.abs(diff) === 1
? diff
: 0;
}
console.log(results);
The idea is simple: we don't need to compare two neighbors twice. ) It's enough to raise a kind of sequence flag if this comparation starts a sequence, and lower it if no sequence is there.
Identify groups of continuous numbers in a list
more_itertools.consecutive_groups
was added in version 4.0.
Demo
import more_itertools as mit
iterable = [2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 20]
[list(group) for group in mit.consecutive_groups(iterable)]
# [[2, 3, 4, 5], [12, 13, 14, 15, 16, 17], [20]]
Code
Applying this tool, we make a generator function that finds ranges of consecutive numbers.
def find_ranges(iterable):
"""Yield range of consecutive numbers."""
for group in mit.consecutive_groups(iterable):
group = list(group)
if len(group) == 1:
yield group[0]
else:
yield group[0], group[-1]
iterable = [2, 3, 4, 5, 12, 13, 14, 15, 16, 17, 20]
list(find_ranges(iterable))
# [(2, 5), (12, 17), 20]
The source implementation emulates a classic recipe (as demonstrated by @Nadia Alramli).
Note: more_itertools
is a third-party package installable via pip install more_itertools
.
How to find the groups of consecutive elements in a NumPy array
Here's a lil func that might help:
def group_consecutives(vals, step=1):
"""Return list of consecutive lists of numbers from vals (number list)."""
run = []
result = [run]
expect = None
for v in vals:
if (v == expect) or (expect is None):
run.append(v)
else:
run = [v]
result.append(run)
expect = v + step
return result
>>> group_consecutives(a)
[[0], [47, 48, 49, 50], [97, 98, 99]]
>>> group_consecutives(a, step=47)
[[0, 47], [48], [49], [50, 97], [98], [99]]
P.S. This is pure Python. For a NumPy solution, see unutbu's answer.
Check for consecutive numbers
Enumerable has a really handy method called each_cons
that works like this:
[1,2,3,4].each_cons(2).to_a # => [ [1, 2], [2, 3], [3, 4] ]
That is, it yields each consecutive set of n elements. In our case n is 2.
Of course, as the name implies, it returns an Enumerator, so we can chain it with other Enumerable methods like all?
:
def four_consecutive?(arr)
return false unless arr.size == 4
arr.each_cons(2).all? {|a, b| b == a + 1 }
end
four_consecutive?([2,3,4,5]) # => true
four_consecutive?([2,2,2,5]) # => false
four_consecutive?([1,2,3,4,5]) # => false
This method has the advantage above others that, because all?
short-circuits as soon as the block returns false, it will only test numbers until it finds a pair that don't meet the condition (b == a + 1
). Of course, with only four elements this doesn't really make a difference—unless you're calling this method thousands of times in situation where performance matters.
Related Topics
Rails Activerecord: Saving Nested Models Is Rolled Back
No Such File to Load -- Soap4R -- Why
Instantiate Capybara Browser and Set a Proxy
How to Create Nested Model from Partial Rails 6
Ruby Roo Loaderror: Cannot Load Such File -- Spreadsheet/Note
Slicing of Arrays in Ruby Returns Different Result - Nil VS. Empty Array
+= Operator Overloading in Ruby
What Is a Very Simple Authentication Scheme for Sinatra/Rack
Rails 3 + Daemons Gem: Exception When Querying Model
Rails 3 - Has_And_Belongs_To_Many
How to Render the Ajax Response in Rails
Sum of All Amount If Charge Dates Are the Same in Stripe
Compass CSS Framework - Using Bootstrap with SASS
Invalid Route Name, Already in Use: 'Admin_Root' (Argumenterror) - Failed Activeadmin Install