Магические числа по сравнению с именованными константами

Вы можете использовать Array.reduce для индексации ваших объектов по ключу (proyectId), а затем использовать Object.values для получения только значений:

const input = [{'proyectId': 1, 'fieldName': 'dog', 'fieldValue': 'wof'}, {'proyectId': 1, 'fieldName': 'cat', 'fieldValue': 'meow'}];

const result = Object.values(input.reduce((map, {proyectId, ...fields}) => {
  map[proyectId] = map[proyectId] || {proyectId, customFields: []};
  map[proyectId].customFields.push(fields);
  return map;
}, {}));

console.log(result);

PS: пожалуйста, поделитесь своими попытками в следующий раз, как предлагалось ранее.

15
задан nickf 4 March 2009 в 00:51
поделиться

22 ответа

86400 не в порядке, так как можно легко ввести его с опечаткой как 84 600, 88400, и т.д.

Введенная с опечаткой константа будет ошибкой компиляции

40
ответ дан 30 November 2019 в 23:48
поделиться

Я сказал бы, что ЧАС, МИНУТА и ДЕНЬ прекрасны. Хождение более детализированного, кажется, не обеспечивает намного больше удобочитаемости.

-1
ответ дан 30 November 2019 в 23:48
поделиться

Я использую названные константы

  • Если число собирается появиться в нескольких местах
  • Если число могло бы когда-либо изменяться (новая конфигурация, новый проект)

Иногда я встраиваю число как подсказка удобочитаемости.

#define LPP57   57     // Lines per page

и т.д.

0
ответ дан 30 November 2019 в 23:48
поделиться

Я могу просить downvotes здесь, но я полагаю, что ни один из Ваших примеров не магические числа. Они - четко определенные универсальные константы, которыми Вы никогда не должны будете заменять с чем-то еще.

Мой подход является соединением некоторых предыдущих ответов:

// properly named variables
int daysBeforeFriday = 4;

// expanded math expressions
int minutesBeforeFriday = 4 * 24 * 60;

// 4 days in seconds (clarification comments)
int secondsBeforeFriday = 4 * 24 * 60 * 60;

// etc..

Я, однако, предварительно вычислил бы определенные выражения в константе в случаях, где включенные значения не очевидны, или оптимизация и/или воспроизводимость являются проблемами (значения с плавающей точкой и их погрешности округления, например).

Простите мне за использование C как пример этого последнего случая, но посмотрите здесь для понимания то, что я имею в виду.;)

0
ответ дан 30 November 2019 в 23:48
поделиться

Это зависит немного от языка, но я создал бы тип. Тем путем Вы сможете считать намерение кода, а также наличие системы проверки типа проверяют часть того намерения во время компиляции и/или времени выполнения.

Константы скрыты в соответствующим образом именованных методах и не повторяются (Вы можете единица тестировать тип/константы, если Вы хотите к).

Конечно, могут быть некоторые проблемы оптимизации/производительности с этим подходом в некоторых случаях. Но по моему опыту они редко имели значение.

например, для иллюстрации что-то как:

class Time
{
   private long time;

   Time(long hours, long minutes, long seconds, long milliseconds) { ... }
   Time(long milliseconds) { ... }

   Time addMilliseconds(long increment)
   {
      return new Time(time + increment));
   }

   Time addSeconds(long increment)
   {
      return addMilliseconds(increment * 1000);
   }

   Time addMinutes(long increment)
   {
      addSeconds(increment * 60);
   }       

   Time addHours(long increment)
   {
      addMinutes(increment * 60);
   }

   [...]

   long getTimeInMilliseconds() { ... };
   long getTimeInSeconds() { ... };
   long getTimeInMinutes() { ... };

   [.. maybe some static factory methods ...]
}

Который может использоваться как это:

Time oneHourAhead = new Time(now()).addHours(1);
Time tenMinutesAgo = new Time(now()).addMinutes(-10);
Time oneHourTenMinutesAhead = new Time(now()).addHours(1).addMinutes(10);
0
ответ дан 30 November 2019 в 23:48
поделиться

Для удобочитаемости важно, чтобы Ваши константы включали единицы измерения. Иначе

$x = время () + ЧАС;

едва немного лучше. Как мы знаем, что $x, время () функция и постоянный ЧАС являются всеми числами в единицах секунд? Ну, мы не можем переименовать время () функция, но мы можем, по крайней мере, записать

$x_seconds = время () + SECONDS_PER_HOUR;

и теперь это ясно без потребности в комментарии.

В этом отношении, как мы знаем, что Вы не делаете строки concatentation, т.е. добавляете суффикс "," или "пополудни". Вы могли бы сказать "хорошо, никто в их правильном уме не будет звонить в тот час", но я не так уверен.

Некоторые люди защищают Венгерскую запись с этой целью. Мне не нравится форма венгерского языка, который украшает имена их базовым типом (интервал, дескриптор, и т.д.), но мне действительно нравится художественное оформление с семантическим типом (секунды).

0
ответ дан 30 November 2019 в 23:48
поделиться
$x = time() + HOUR;
$y = time() + DAY;
$z = time() + WEEK;

Как насчет волшебных строк? Я склонен делать вещи как это:

  $x = strtotime('now + 1 hour');
  $y = strtotime('now + 1 day');
  $z = strtotime('now + 1 week');

Да, это, вероятно, работает незначительно медленнее. Но в большей схеме вещей, это действительно имеет значение?

0
ответ дан 30 November 2019 в 23:48
поделиться

Я определенно использовал бы константы, в то время как можно посмотреть 86400 и как 24 часа, будущий программист, делающий обслуживание, не мог бы быть настолько ярким и будет царапать голову на том, что точно означает то число. Это также имеет место для Вас, если Вы возвращаетесь один день и забыли что 86 400 средств.

0
ответ дан 30 November 2019 в 23:48
поделиться

Лично, мне нравится иметь именованные константы в случае, если я должен изменить значение константы затем, я только должен сделать это в одном месте.

0
ответ дан 30 November 2019 в 23:48
поделиться

День всегда будет иметь 24 часа, и час будет всегда составлять 60 минут.

Я думаю точка к именованию их, как описательные константы - то, где a) числовое значение не ясен (604800?) b) значение может когда-нибудь измениться

0
ответ дан 30 November 2019 в 23:48
поделиться

Работа над высшим уровнем доступной абстракции.

Пример Ruby ActiveSupport

3.months.ago
1.year.from_now

Тот же принцип может быть применен к другим менее выразительным языкам также, Java позволит Вам делать что-то как:

TimeHelper.months().ago(3);

Если у Вас нет объектов на Вашем языке, можно сделать это:

$x = strtotime('now + 1 hour');
$y = strtotime('now + 1 day');
$z = strtotime('now + 1 week');

Намного меньше комнаты для неверного истолкования. Почему скрипка с вещами ниже проблемной области, если Вы не имеете к?

-1
ответ дан 30 November 2019 в 23:48
поделиться

Я разграничил бы на основе размера проекта. Чем больше проект, тем больше абстракций и констант... Настолько простой.

1
ответ дан 30 November 2019 в 23:48
поделиться

Я удерживаю простой; название переменной и комментария (в случае необходимости в случае очень волшебных чисел) будет достаточно для передачи обзора кода.

int someDelay = 1232323; // in milliseconds.
2
ответ дан 30 November 2019 в 23:48
поделиться

Я склонен использовать константы по магическим числам почти исключительно. Я думаю, что это увеличивается четко и дает Вам одну точку в программе для фиксации любых ошибок. Существует несколько волшебных '60-х, например: 60 секунд за минуту, 60 минут за час.

2
ответ дан 30 November 2019 в 23:48
поделиться

Для использования в единицах как это хороший прием должен назвать все единицы (даже основа), тот путь Ваши чтения кода как правильно указанное измерение:

// The base unit of time is the second
const double second = 1.0;
const double ns = 1e-9 * second;
const double micros = 1e-6 * second;
const double ms = 1e-3 * second;
const double minute = 60.0 * second;
const double hour = 60 * minute;
const double day = 24 * hour;
const double week = 7 * day;
const double year = 365.24 * day; 

затем всегда используйте соответствующую единицу в своем коде

// Set up a 90 second timeout
timeout(90*second);

или

elapsedDays = floor(elapsedtime / day);

Вы видите эту формулировку в различных научных пакетах (например, Geant4) время от времени.

3
ответ дан 30 November 2019 в 23:48
поделиться

Я говорю моим студентам это:

Если можно прочитать код без комментариев затем нет никакой потребности в константах. Если Вы должны иметь, объясняет код затем, ему нужны комментарии.

Я также говорю им:

Взгляды плохи. В том, что если Вы пишете код, который делает людей, должны вырыть через него для понимания его, который не является хорошей вещью.

Так, если можно показать, что строки коллеге и они могут понять это без констант, Вы (вероятно), хороши без них. Вероятно, Вы захотите константы.

4
ответ дан 30 November 2019 в 23:48
поделиться

Лично я использовал бы SECS_PER_MIN, SECS_PER_HOUR, и т.д. Я, как даже было известно, использовал NANOS_PER_SEC при случае. Я всегда делал бы это, если бы язык испытал недостаток в экспоненциальном представлении целочисленных литералов.

Это не об удобочитаемости, точно. Причина использования SECS_PER_DAY, а не 86400 только не относится к тому, какие общие знания мы ожидаем читателя. Это о самодокументировании кода, что означает однозначно показывать Вашу работу.

Несомненно, все знают, что за минуту существует 60 секунд. Но они также знают, что за час существует 60 минут. При использовании литеральных 60, вероятно, очевидно, что код предназначается, чтобы сделать. Но почему рискуют?

Если Вы используете SECS_PER_MIN, то определенно очевидно, что Вы преобразовываете время в минутах (всего 1 минута в Вашем примере) ко времени в секундах. Вы, например, не добавляете один час ко времени, измеряемому в минутах, или один градус к углу в минутах. Вы не добавляете 5 футов к длине, измеряемой в дюймах.

Названные константы обеспечивают больше контекста для окружающего кода. Для Вашего примера добавления времени мы знаем только путем рассмотрения одной строки, что $x должен быть временем в секундах. Название константы повторяет, что $x не является временем в millis или тактами системных часов, или микродве недели. Это помогает всем проверить и поддержать правильность единиц: они могут сказать путем взгляда, что то, что Вы намеревались сделать, - то, что Вы на самом деле сделали. Они никогда не должны даже развлекать понятие, что Вы намеревались добавить 60 millis ко времени, измеряемому в millis, но поняли его превратно, потому что $x был на самом деле в секундах.

Названные константы также помогают избежать опечаток. Несомненно, все знают, что за день существует 86 400 секунд. Это не обязательно следует за этим, они не будут опечатка это как 84 600, или что они сразу определят ошибку, если кто-то еще будет иметь. Предоставленный у Вас есть полное тестирование, таким образом, такая ошибка никогда не превращала бы его в поле, но самый эффективный способ зафиксировать его состоит в том, чтобы предотвратить дефектный код, добирающийся до теста во-первых. Таким образом, я определил бы константы как это (или безотносительно синтаксиса):

SECS_PER_MIN := 60; 
SECS_PER_HOUR := 60 * SECS_PER_MIN;
SECS_PER_DAY := 24 * SECS_PER_HOUR;
SECS_PER_WEEK := 7 * SECS_PER_DAY;

Или, если другие константы были необходимы так или иначе (который в случае времени они, вероятно, не будут, потому что Вы нормализуете все в secs при первой возможности для сокращения шанса беспорядка):

SECS_PER_MIN := 60;
MINS_PER_HOUR := 60;
HOURS_PER_DAY := 24;
DAYS_PER_WEEK := 7;

SECS_PER_HOUR := SECS_PER_MIN * MINS_PER_HOUR;
etc.

Отметьте порядок на RHS: минуты явно "отменяют", делая работу еще более четкой. Не такое грандиозное предприятие со временем, но хорошо установить последовательную схему рано, так, чтобы, когда вещи становятся противными позже (CLOCKS_PER_SEC, PLANCK_LENGTHS_PER_PARSEC) можно было получить его правильные использующие знакомые методы.

4
ответ дан 30 November 2019 в 23:48
поделиться

Существует относительно хороший аргумент затем любое число кроме нуля, или нужно быть именованной константой. Даже в Вашем примере, где Вы утверждаете, что у Вас нет проблемы с удобочитаемостью 86 400, существует все еще некоторая неоднозначность о том, какова Ваша единица измерения.

Если бы я поддерживал Ваш код, то я предпочел бы видеть названный константами как:

const int secondsInDay = 86400;

.. не большая неоднозначность там.:) Зависит от ли любой (включая себя.. Я имею в виду, я изо всех сил пытаюсь помнить то, что я записал на прошлой неделе, уже не говоря о прошлом годе!) потребуется, чтобы поддерживать Ваш код на некотором этапе.

6
ответ дан 30 November 2019 в 23:48
поделиться

Я пошел бы константы (или некоторая жеманная производная, как направляющие 15.minutes конвенция) в значительной степени везде. Для меня это об упрощении "ввода" всего этого; если я вижу "10 * МИНУТЫ" где-нибудь в строке, я знаю, что имею дело со временем (или чей-то для удара задницы). Если я вижу 10 * 60, или 600 совершенно возможно, что я не мог бы grok, что мы имеем дело со временем вполне так легко.

8
ответ дан 30 November 2019 в 23:48
поделиться

Мой подход к не используемые названные константы, но разделите единицы как это:

long twelvePM = 12 * 60 * 60 * 1000L;
long timeout = 60 * 1000L;

Таким образом, ясно, что это находится в миллисекундах, и их легко скорректировать в случае, если я хочу изменить значения позже.

4
ответ дан 30 November 2019 в 23:48
поделиться

Один из моих преподавателей однажды сказал нам не помещать любые магические числа в наш код кроме 1,-1, и 0. Это - немного экстремального значения, но оно врезается в мою память и все еще ведет меня, хотя я не придерживаюсь его полностью.

В Вашем примере я предпочел бы символьные имена во всех случаях.

16
ответ дан 30 November 2019 в 23:48
поделиться

Мое эмпирическое правило при обучении (так, больше правил ядра, чем в реальной жизни) было любым числом кроме-1, 0, 1, или 2, который использовался, несколько раз ДОЛЖНА была быть константа. При использовании его только однажды можно просто прокомментировать это, если Вы предпочитаете...

2
ответ дан 30 November 2019 в 23:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: