What's the best way to implement `next` and `previous` on an enum type?
Try this:
public enum A {
X, Y, Z;
private static final A[] vals = values();
public A next() {
return vals[(this.ordinal() + 1) % vals.length];
}
}
Implementation of previous()
is left as an exercise, but recall that in Java, the modulo a % b
can return a negative number.
EDIT: As suggested, make a private static copy of the values()
array to avoid array copying each time next()
or previous()
is called.
Java get next Enum value or start from first
Yeah sure, it goes like this
public Cars getNextCar(Cars e)
{
int index = e.ordinal();
int nextIndex = index + 1;
Cars[] cars = Cars.values();
nextIndex %= cars.length;
return cars[nextIndex];
}
Is there an increment operator ++ for Java enum?
You can't "increment" an enum, but you can get the next enum:
// MyEnum e;
MyEnum next = MyEnum.values()[e.ordinal() + 1];
But better would be to create an instance method on your enum.
Note well how the problematic next value is handled for the last enum instance, for which there is no "next" instance:
public enum MyEnum {
Alpha,
Bravo,
Charlie {
@Override
public MyEnum next() {
return null; // see below for options for this line
};
};
public MyEnum next() {
// No bounds checking required here, because the last instance overrides
return values()[ordinal() + 1];
}
}
So you could do this:
// MyEnum e;
e = e.next();
The reasonable choices you have for the implementation of the overidden next()
method include:
return null; // there is no "next"
return this; // capped at the last instance
return values()[0]; // rollover to the first
throw new RuntimeException(); // or a subclass like NoSuchElementException
Overriding the method avoids the potential cost of generating the values()
array to check its length. For example, an implementation for next()
where the last instance doesn't override it might be:
public MyEnum next() {
if (ordinal() == values().length - 1)
throw new NoSuchElementException();
return values()[ordinal() + 1];
}
Here, both ordinal()
and values()
are (usually) called twice, which will cost more to execute than the overridden version above.
How to get next (or previous) enum value in C#
Thanks to everybody for your answers and feedback. I was surprised to get so many of them. Looking at them and using some of the ideas, I came up with this solution, which works best for me:
public static class Extensions
{
public static T Next<T>(this T src) where T : struct
{
if (!typeof(T).IsEnum) throw new ArgumentException(String.Format("Argument {0} is not an Enum", typeof(T).FullName));
T[] Arr = (T[])Enum.GetValues(src.GetType());
int j = Array.IndexOf<T>(Arr, src) + 1;
return (Arr.Length==j) ? Arr[0] : Arr[j];
}
}
The beauty of this approach, that it is simple and universal to use. Implemented as generic extension method, you can call it on any enum this way:
return eRat.B.Next();
Notice, I am using generalized extension method, thus I don't need to specify type upon call, just .Next()
.
How can I elegantly find the next and previous value in a Python Enum?
Note that you can provide succ
and pred
methods inside an Enum
class:
class Sequential(Enum):
A = 1
B = 2
C = 4
D = 8
E = 16
def succ(self):
v = self.value * 2
if v > 16:
raise ValueError('Enumeration ended')
return Sequential(v)
def pred(self):
v = self.value // 2
if v == 0:
raise ValueError('Enumeration ended')
return Sequential(v)
Used as:
>>> import myenums
>>> myenums.Sequential.B.succ()
<Sequential.C: 4>
>>> myenums.Sequential.B.succ().succ()
<Sequential.D: 8>
>>> myenums.Sequential.B.succ().succ().pred()
<Sequential.C: 4>
Obviously this is efficient only if you actually have a simple way to compute the values from an item to the next or preceding one, which may not always be the case.
If you want a general efficient solution at the cost of adding some space, you can build the mappings of the successor and predecessor functions.
You have to add these as attributes after the creation of the class (since Enum
messes up attributes) so you can use a decorator to do that:
def add_succ_and_pred_maps(cls):
succ_map = {}
pred_map = {}
cur = None
nxt = None
for val in cls.__members__.values():
if cur is None:
cur = val
elif nxt is None:
nxt = val
if cur is not None and nxt is not None:
succ_map[cur] = nxt
pred_map[nxt] = cur
cur = nxt
nxt = None
cls._succ_map = succ_map
cls._pred_map = pred_map
def succ(self):
return self._succ_map[self]
def pred(self):
return self._pred_map[self]
cls.succ = succ
cls.pred = pred
return cls
@add_succ_and_pred_maps
class MyEnum(Enum):
A = 0
B = 2
C = 8
D = 18
Used as:
>>> myenums.MyEnum.A.succ()
<MyEnum.B: 2>
>>> myenums.MyEnum.B.succ()
<MyEnum.C: 8>
>>> myenums.MyEnum.B.succ().pred()
<MyEnum.B: 2>
>>> myenums.MyEnum._succ_map
{<MyEnum.A: 0>: <MyEnum.B: 2>, <MyEnum.C: 8>: <MyEnum.D: 18>, <MyEnum.B: 2>: <MyEnum.C: 8>}
you probably want a custom exception instead of KeyError
but you get the idea.
There probably is a way to integrate the last step using metaclasses, but it's notstraightforward for the simple fact thatEnum
s are implemented using metaclasses and it's not trivial to compose metaclasses.
Next or previous enum
You are trying to solve the wrong problem. This is far too complex for a simple enum to calculate. Refactor the enum to a class and use a comparison interface.
If this route is open to you look at how this could be implemented by a class:
public class TimeFrame: IComparable
{
private int days;
public int Days
{
set
{
days = value;
}
}
public int CompareTo(object other)
{
//see this for implementation -- http://msdn.microsoft.com/en-us/library/system.icomparable.aspx#Mtps_DropDownFilterText
}
public string Description
{
get code to return the description string , ie "1-3 months"
}
}
Get Next item in Enum and return first if last+1
Add modulo arithmetics to husayt's answer
How to get next (or previous) enum value in C#
Code:
public static class Extensions {
public static T Next<T>(this T src) where T : struct {
if (!typeof(T).IsEnum)
throw new ArgumentException(String.Format("Argument {0} is not an Enum",
typeof(T).FullName));
T[] Arr = (T[])Enum.GetValues(src.GetType());
int j = (Array.IndexOf<T>(Arr, src) + 1) % Arr.Length; // <- Modulo % Arr.Length added
return Arr[j];
}
}
Changing enum to next value [C++11]
As noted by Maroš Beťko, to add 1 to a variable, you have to cast the value to int
and back:
activeDraw = static_cast<drawMode>(static_cast<int>(activeDraw) + 1);
If the enum is defined without the C++11 enum class
syntax (like in the question's text), the casting to int
is not necessary:
activeDraw = static_cast<drawMode>(activeDraw + 1);
To make it cycle back to zero, use integer arithmetic, modulo operator:
activeDraw = static_cast<drawMode>((activeDraw + 1) % (ATMOSPHERE + 1));
To eliminate one ugly +1
, add another element to the enum:
enum drawMode { ..., ATMOSPHERE, NUM_DRAW_MODES };
...
activeDraw = static_cast<drawMode>((activeDraw + 1) % NUM_DRAW_MODES);
You can also stuff this code into a operator++
if you use it very often:
drawMode operator++(drawMode& mode)
{
mode = static_cast<drawMode>((mode + 1) % NUM_DRAW_MODES);
return mode;
}
drawMode operator++(drawMode& mode, int) // postfix operator
{
drawMode result = mode;
++mode;
return result;
}
Overloading operators for enum
s is rarely used, and some people consider it overkill (bad), but it will make your code shorter (and arguably cleaner).
Given an existing key how to get the next or previous key in an ordered typescript string enum?
Take a look how string enum is transpiled to JS:
var STEPS;
(function (STEPS) {
STEPS["NAME"] = "name";
STEPS["GENDER"] = "gender";
STEPS["BIRTHDAY"] = "birthday";
STEPS["SUCCESS"] = "success";
})(STEPS || (STEPS = {}));
Knowing that:
enum STEPS {
NAME = "name",
GENDER = "gender",
BIRTHDAY = "birthday",
SUCCESS = "success"
}
const vals = Object.values(STEPS);
const indexOfSearchedItem = vals.indexOf(STEPS.GENDER);
const next: STEPS = vals[indexOfSearchedItem + 1]
console.log(next);
Related Topics
How to Create a New Packaging Type for Maven
How to Unit Test Abstract Classes: Extend with Stubs
Native Query with Named Parameter Fails with "Not All Named Parameters Have Been Set"
Java User.Home Is Being Set to %Userprofile% and Not Being Resolved
Why Are Exceptions Not Checked in .Net
Compile Time VS Run Time Dependency - Java
Spring Cron Expression for Every Day 1:01:Am
Transaction Isolation Levels Relation with Locks on Table
Java 8 Default Methods as Traits:Safe
How Do Determine If an Object Is Locked (Synchronized) So Not to Block in Java
Java Stanford Nlp: Part of Speech Labels
Cannot Assign Requested Address Using Serversocket.Socketbind
No Serializer Found for Class Org.Hibernate.Proxy.Pojo.Bytebuddy.Bytebuddyinterceptor
Command Line Progress Bar in Java
Good Examples Using Java.Util.Logging
Intellij - Convert a Java Project/Module into a Maven Project/Module