Pull to refresh

Comments 13

К сожалению, Dictionary<,> в общем случае не сохраняет порядок добавления ключей. Если я не ошибаюсь, порядок теряется при перебалансировке. В вашем случае лучше подойдет просто список пар (ну или Tuple-ов).
Да, это верно для v1. Вариант v2 использует Dictionary как ассоциативный массив.
И еще пару слов про код — очень плохая практика использовать в методах, которые вызываются в linq сайд эффекты — присваивание переменных и подобное:
Dictionary<char, int> ra = w.ToDictionary(ch => ch, ch => (o = ("" + o)[0] == '1' ? o * 2 : o * 5) / 2);

Если вам нужны локальные переменные — используйте let. Плюс странная констркуция ("" + o)[0] — это первый символ числа? Тогда пишите явно o.ToString()[0]. Но все равно присовение внутри linq функций — это плохо. Тоже самое и здесь
num.Select((c, i) => ++i < num.Length && ra[c] < ra[num[i]] ? -ra[c] : ra[c])

++i лучше заменить на i+1.
И во втором ToRoman.

Также нежелательно смешивать linq синтаксис и вызовы extension методов. Понятно, что во втором ToRoman нужен последний First(), но тогда либо весь предыдущий запрос писать в linq синтаксисе, либо весь в цепочку вызовов.
очень плохая практика использовать в методах, которые вызываются в linq сайд эффекты — присваивание переменных и подобное
Это утверждение верное, но не надо его возводить в ранг мантры. Аналогичный баг находится у студентов с оператором GOTO. Половина знает о его существовании, но все утверждают, что им пользоваться нельзя. И громоздят в коде флаги, дополнительные переменные для выхода из вложенных циклов.

Конкретно в этом фрагменте кода локальная статическая переменная используется только раз при первом обращении к классу. Единственный вред от нее — занимает 4 байта памяти. Даже многопоточность не может привести к конфликту в коде генерации словоря. Во втором случае использования переменной будут конфликты потоков.
Также нежелательно смешивать linq синтаксис и вызовы extension методов
Согласен, что «нежелательно». С другой стороны, декартово произведение проще получить в linq синтаксисе. Аналог оператора let через вызовы extension методов мне неизвестен.
PS: Позже сделаю еще одну LINQ-версию, исправленную.
Ну уж нет, именно в ранг мантры. Такой код сложно читать, практически невозможно рефакторить. То же самое касается goto. Такой код в продакшене — повод поговорить про профнепригодность.

Аналог let — это Select с анонимным типом внутри.

А вы действительно учите этому студентов?
Аналог let — это Select с анонимным типом внутри.
Невозможно переписать значение переменной объявленной оператором let и поля анонимного класса тоже ReadOnly. Почему у вас такое отторжение к механизму замыкания переменных?
А вы действительно учите этому студентов?
Учу много чему и с очень давних времен. Есть чем гордиться. Сейчас только один предмет веду близкий по содержанию к Data Mining. А LINQ студентам рассказал, чтобы они не городили мне горы циклов. (про уход от темы и ваш вариант ниже).
Я совершенно не против замыканий. Я против использования нечистых функций в linq в частности и в функциональных подходах (linq, как ни крути, это кусочек функционального мира в императивном C#) в общем. Все ваши примеры можно переписать с использованием чистых функций, и, отвечая на ваш вопрос ниже, они вполне подходят для обучения студентов. Горы циклов, это, конечно, не очень, но такое использование linq, на мой взгляд, усложняет его понимание и уводит несколько в сторону от его базовых понятий — комбинации функций, ленивые вычисления и так далее.
Также нежелательно смешивать linq синтаксис и вызовы extension методов

Чем смешивать плохо, какие аргументы?

Я имею в виду такое, допустим код вида
(from b in a where .... select ...).ToArray(...).Where(...) ...

То ее если ее переписать в длинную цепочку как
a.Where(...).Select(...).ToArray(...).Where(...) ...

То дебажить и исследовать их одинаково тяжело, а вот читать первую мне больше нравится. Особенно, если в выражении есть group by и join, которые в extension методах смотрятся очень плохо.

Было бы здорово услышать аргументы против
Код v2 предлагается использовать для анализа и для проверки способностей кандидатов. Один кандидат опишет алгоритм работы и все недостатки с обоснованием. А другой может эмоционально ругаться и отказываться вникать в код. Вы которого на работу возьмете?
Второго. Если б я увидел такой код на собеседовании — я бы усомнился в адекватности собеседующих и задумался о вакансии в принципе. Мне придется разбираться с таким кодом на работе? Вы реально так пишите? Какие мои навыки вы проверяете?
Какие мои навыки вы проверяете?
Мышление и способность видеть алгоритм за набором символов. Знание базового синтаксиса C#
Вы реально так пишите?
Для своего проекта могу написать подобный код. Например, парсер. Без генераторов. Ведь никого не смущает переменные и константы из алгебры a,b,c,d,x. Кроме того, такой код использую только для вещей, где говорящие названия только захламят текст программы, разнесут его на несколько абзацев то, что укладывается в одну строчку. Нет смысла использовать вместо X имя переменной Abscissa, а вместо Y — Ordinate.

Вы от сути тему уводите и переходите на личности. Можете предложить свой вариант решаемой задачи с помощью LINQ?
Я, наверное, неправильно выразился — на личности переходить не хотелось, коненчо. Вопросы сверху — это те вопросы, которые я бы задал на собеседовании в ответ на такое задание.

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

Например, мы на собеседовании даем вот такой вот код «на-объяснить»:

var groupToDictionary = function(arr, keyFunction) {
    var objToReturn = {};

    arr.forEach(function(item) {
        var key = keyFunction(item);

        if (!objToReturn.hasOwnProperty(key)){
            objToReturn[key] = [];
            objToReturn[key].getKey = function() { return key; };
        }

        objToReturn[key].push(item);
    });

    return objToReturn;
};


Банальная функция, на которой, к сожалению, многие отваливаются. Но функция реальная, без подвохов.
Sign up to leave a comment.

Articles