Следуя предложению Джошуа, вы можете подсчитать количество наблюдений в вашем фрейме df
, где Year
= 2007 и Month
= Nov (если они столбцы):
nrow(df[,df$YEAR == 2007 & df$Month == "Nov"])
и с aggregate
, следуя @GregSnow:
aggregate(x ~ Year + Month, data = df, FUN = length)
Код станет неуправляемым, прежде чем вы нажмете любой предел, который накладывает Java.
Рассматривали ли вы рефакторинг кода? В зависимости от того, для чего создан оператор switch, вы можете либо:
Итак, в вашем случае вам было бы лучше определить статический Map
значений индекса для Classes
:
public class MyClass
{
private static final Map<Integer, Class> LOOKUP =
new HashMap<Integer, Class>(...);
static
{
LOOKUP.put(0, Adidas.class);
LOOKUP.put(1, Affin.class);
...
}
public void onItemClick(...)
{
...
// Replace switch statement with:
if (LOOKUP.containsKey(index))
{
startActivity(new Intent(Search.this, LOOKUP.get(index)));
}
else
{
Toast.makeText(Search.this,
"Invalid Selection",
Toast.LENGTH_SHORT).show();
}
}
...
}
Это облегчает чтение кода в onItemClick()
. Вы можете сделать еще один шаг и определить частный метод startActivity()
, который использует индекс, который будет использоваться, и содержит весь код замены оператора switch.
Ограничение на максимальную длину метода: Максимальный размер метода в java?
В противном случае, в качестве примера, switch
с 1000 случаями форма
case
n : System.out.println(
n ); break;
, похоже, работает. Сгенерированный байт-код использует инструкцию tableswitch
, что означает, что она даже не должна быть неэффективной.
Конечно, если это не автоматически сгенерированный код, это будет неодобрительно
Подумайте об альтернативах, таких как:
Изменить:
По-видимому, глядя на ваш код, поскольку все ваши операторы case работают с одним и тем же типом кода, все, что вам нужно, это Class[]
, к которому обращается index
, что-то вроде:
Class[] myArray = new Class[...];
myArray[0] = Adidas.class;
//...
//instead of the switch
startActivity(new Intent(Search.this, myArray[index]));
И конечно, было бы красивее, если бы был способ произвести эти классы каким-то другим способом, скажем, если бы у вас были объекты Adidas
и Affin
, и вы запустили getClass()
на них, или если у вас был список их имена и могут использовать Class.forName
.
Я не знаю точно, что делает ваш метод startActivity()
, даже не знаю, как реализуется объект Intent
, но я думаю, что альтернативный способ решить вашу проблему может быть:
Shop
(например); Adidas
или Affin
; startActivity()
для каждого класса; Например:
public interface Shop
{
void startActivity(Intent i);
}
Затем для каждого класса .. .
public class Adidas implements Shop
{
public Adidas(){
// ...
}
public void startActivity(Intent i)
{
// specific implementation
}
}
Наконец, в вашем клиентском коде
Shop[] shops = new Shop[]{ new Adidas(), new Affin(), ... };
for (Shop shop : shops)
{
shop.startActivity(new Intent(Search.this));
}
Или вы можете взглянуть на шаблон стратегии. Например:
Если это выглядит так:
switch (calculation type)
{
case: Fibonacci { ... }
case: Pithagoras { ... }
...
case 104 : { ... }
}
Вы можете реорганизовать его с помощью шаблона стратегии, например, следующим образом:
CalculationStrategy strategy = strategyFactor.getStrategy(calculation type);
strategy.doCalculation;
Happy кодирование! Dave
Коммутатор отлично работает с байтом, коротким, char и int. Таким образом, у вас есть ограничение значений int + default. Из здесь
Но я предлагаю больше думать об архитектуре. Лучше организовать некоторый интерфейс «исполнитель» и реализовать некоторое количество этого исполнителя (может быть как внутренние классы). Тогда вам нужно только иметь массив (карту), где у вас будут условия и примеры этих исполнителей. Идея состоит в том, чтобы отделить данные от алгоритма.
Также вы можете попытаться найти другие шаблоны для этого
Один из возможных вариантов - переместить / перестроить этот код на «Chain of Responsibility patter», учитывая, что эти операторы switch не просто возвращаются, какая-то обработка на них и т. д.
Я считаю, что вы не есть также и использование диапазонов Гуава (другими словами, у вас в каждом случае есть описатель, а не обычная обработка на двух (более одного) случая.
При реализации коммутаторов можно сделать много оптимизаций для производительности, иначе вам придется перечислить все переключатели до тех пор, пока они не совпадут.
Что бы я сделал здесь, есть основной набор переключателей для первого символ, а затем вложенные переключатели внутри, поэтому, если выбор был z, ему не нужно проверять каждое имя сначала
switch(FIRSTCHAR){
case A: switch(index){
case 0: ..... break;
etc
}
break;
case B://do the same
}
. Другой способ заключается в том, чтобы разбить оператор коммутатора на меньшие операторы равного размера. Это быстрее из-за того, как скомпилирован байт-код (ref настройки производительности Java - shirazi)