• Чем меньше символов, пробелов и пропусков в коде, тем лучше?

    Не правильно.

    Код должен быть читаем и понятен человеку. Причем, не только автору, но и «злому маньяку тим-лиду, который вооружен и знает, где вы живёте», как говорится в шутке программистов.
    Для этого пустые строки между блоками кода бывают полезны. Как и комментарии, и длинные осмысленные наименования переменных и фукций.
    Компилятор потом всё равно всё перелопатит по-своему в ацкие бинарные инструкции )

    Как форматировать код — договариваются. Есть общепринятые стандарты форматирования кода (coding style). Например, стандартный для PHP. Или принятый в компании AirBnB для JavaScript.

    Хороший-удобный редактор кода всегда подскажет, где накосячили со стилем вашего кода, почему, и как исправить.
    Ответ написан
    Комментировать
  • Как на JS правильно конвертировать миллисекунды в формат 00:00:00,000?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    JS в браузере считает даты в часовом поясе браузера.
    timestamp в миллисекундах однозначно задаёт момент времени в зоне UTC.
    В это момент, например, в Москве на 3 часа больше. Поэтому браузер покажет
    Mon Mar 20 2023 07:42:33 GMT+0300 (Moscow Standard Time)


    Excel, видимо, предпочитает UTC, поэтому у него получилось 04:42

    Раз хочется получить именно в UTC, можно так:
    (new Date(1679287353711))
      .toISOString() // "2023-03-20T04:42:33.711Z"
      .substring(11, 23) // "04:42:33.711"
    ;
    Ответ написан
    Комментировать
  • Как с помощью регулярок на js заменить в тексте слова, которые могут ялвяться частью других слов?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Регулярные выражения не инструмент, который умеет понимать корень слова. Как уже написали в комментариях, с числом букв споткнётесь о коллизию «думой» vs «думал» – первое надо капитализировать, второе нет.

    Так что предложил бы засучить рукава и перечислить все словоформы явно. Но и это не гарантирует безошибочность: подставят переносы слова, или омонимы.
    Омонимы сидели в баре, развалившись, как баре.


    В помощь
    учебник по регулярным выражениям.

    Граница слова: \b — работает только для ASCII, не годится для Unicode кириллицы.

    Unicode и флаг "u"

    Вариант выражения
    /дум.?(?=$|\s)/u – один опциональный символ, и смотреть вперёд, чтобы там был или конец строки или пробельный символ.

    const m = str => str.match(/дум.?(?=$|\s)/u);
    m('ду') // null
    m('дум') // ["дум"]
    m('дума') // ["дума"]
    m('думать') // null


    Вам нужно ещё разобраться и самостоятельно сделать такую же проверку до искомой строки: чтобы там было начало строки ^ или пробельный символ.
    Ответ написан
  • Как определить метод, а не свойство-функцию?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    MDN: Using super in method definitions:
    Only functions defined as methods have access to the super keyword. super.prop looks up the property on the prototype of the object that the method was initialized on.


    Learn.Javascript: Методы, а не свойства-функции
    Свойство [[HomeObject]] определено для методов как классов, так и обычных объектов. Но для объектов методы должны быть объявлены именно как method(), а не "method: function()".

    Для нас различий нет, но они есть для JavaScript.
    Ответ написан
  • PHP websocket насколько сильно он уступает node.js по производительности?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Open Swoole – мощный супер-быстрый асинхронный PHP.
    WebSocket'ы, корутины, высокая нагрузка.

    Пример WebSocket сервера:
    <?php
    
    use OpenSwoole\WebSocket\Server;
    use OpenSwoole\Http\Request;
    use OpenSwoole\WebSocket\Frame;
    
    $server = new Server("0.0.0.0", 9502);
    
    $server->on("Start", function(Server $server)
    {
        echo "OpenSwoole WebSocket Server is started at http://127.0.0.1:9502\n";
    });
    
    $server->on('Open', function(Server $server, OpenSwoole\Http\Request $request)
    {
        echo "connection open: {$request->fd}\n";
    
        $server->tick(1000, function() use ($server, $request)
        {
            $server->push($request->fd, json_encode(["hello", time()]));
        });
    });
    
    $server->on('Message', function(Server $server, Frame $frame)
    {
        echo "received message: {$frame->data}\n";
        $server->push($frame->fd, json_encode(["hello", time()]));
    });
    
    $server->on('Close', function(Server $server, int $fd)
    {
        echo "connection close: {$fd}\n";
    });
    
    $server->on('Disconnect', function(Server $server, int $fd)
    {
        echo "connection disconnect: {$fd}\n";
    });
    
    $server->start();
    Ответ написан
    Комментировать
  • Как сделать такую, переливающеюся всеми цветами радуги текстуру?

    В Photoshop сделать можно через Gradient Map («карту градиента»)

    1. Сделать базовое изображение (можно в градациях серого) с плавными переходами яркости: светлые области станут радужными «горами», темные – полосатыми «низинами». Размыть, чтобы не было мелких деталей, добавить Liquify и всякие другие плавные искажения.

    2. Подготовить градиент, который слева будет чередой белых и черных областей, а ближе к другому краю – радужными переходами ярких цветов.

    3. Использовать этот градиент как карту цветов. В Photoshop это – наложить корректирующий слой Gradient Map поверх изображения.

    У меня наскоро получилось такое:
    скрин
    64161055c3c0d942782847.jpeg

    Вот tutorial с похожим эффектом.
    Ответ написан
    Комментировать
  • Как заменить функционал Sublime Text 3 У visual studio code?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    1. cmd + F2 (на маке) выделит все включения текущего слова. Мульти-курсор, можно заменить или допечатать/удалить часть – везде и сразу ©
    2. поиск в VSCode офигенный. И по документу, и по всему проекту, причем можно открыть несколько «редакторов поиска». Искать и с учётом регистра, совпадением слова целиком, регулярными выражениями. Белый/черный список расширений файлов, папок. Исключить / включить папки типа vendors или node_modules.
    3. cmd + shift + P и начать печатать "Emmet: Balance (inward)" – и выбрать команду
    4. плагин PHP Intelephense, и не забыть отключить VSCode PHP Language Features, как пишут по ссылке в разделе Quick Start


    Скачайте/распечатайте самые популярные клавишные команды VSCode под Windows, под Mac или под Linux.
    Ответ написан
    5 комментариев
  • Как установить macOS без дисковой утилиты?

    вот тут пишут, что вероятно, бук просто не может по сети достучаться до яблочных серваков. Советуют зажать при загрузке клавишу Option, чтобы попасть в Startup manager, где можно выбрать WiFi сеть и ввести её пароль.

    Ещё, теоретически, может не помешает VPN на роутере, чтобы к яблочным серверам подключаться через VPN где-то за рубежом, т.к. есть вероятность, что российские IP блокируются.
    Ответ написан
  • Как превратить массив в число?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Небезопасный плохой вариант:
    const str = '1+1'; // строка
    const result = eval(str); // 2
    плохой кулхацкер передаст не "1+1", а злодейский код, который тупо выполнится и всё сломает.

    Вариант получше: разбивать строку "1+1" на токены: число, операция, число. Предположим, что задача из детского сада, поэтому числа всегда целые, неотрицательные, а операций всего 4: + - * / Разбить можно используя «регулярное выражение», или просто тупо искать в строке один из 4 операторов. С регуляркой примерно так:
    const str = '1+1'; // строка
    const parts = str.match(/(\d+)([-+*\/])(\d+)/); // массив [ "1+1", "1", "+", "1" ]
    if (!parts) throw 'не похоже на арифметику!';
    const [ _, A, op, B ] = parts;
    const a = +A; // из строки в число
    const b = +B;
    
    let result;
    if (op === '+') result = a + b;
    if (op === '-') result = a - b;
    if (op === '*') result = a * b;
    if (op === '/') result = a / b;
    
    console.log('result', result); // 2
    Ответ написан
    Комментировать
  • Как вывести два массива поочередно?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Media.Mname.map(({ name }, i) => `${name} - ${Media.Link[i].link}`)
    // [ "vk - vkontakte", "tg - telegram", "inst - instagram ", "facebook - facebook" ]
    Ответ написан
    Комментировать
  • Как отловить баг на продакшене?

    sergiks
    @sergiks Автор вопроса, куратор тега PHP
    ♬♬
    Нашли опытным путём некоторые действия, которые 100% приводили к нежелательному изменению данных.
    Перерыли весь их код – ничего.

    Глубокой ночью решились временно включить на проде дебажный режим кернела Symfony.

    И повторив запрос, в профайлере нашли причину: один из разработчиков накостылил изменения на проде в /vendor/ доктрин-бридже. Он ошибочно полагал, что это ни на что не повлияет и никак не связано с появившейся проблемой.

    Два дня «веселья».
    Ответ написан
    Комментировать
  • Исправьте, пожалуйста, код на JS. Почему он не работает?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно держать указатель на очередной элемент паттерна удаления.
    И знать ближайшую следующую позицию под удаление.

    В цикле идти по элементам исходного массива. Когда дошли до позиции под удаление, обновить указатель и следующую позицию, и никак не использовать значение. А иначе копировать текущий элемент в результат.
    const arr = Array.from({ length: 50 }, (_, i) => i); // [0, 1, 2, 3, ... 49]
    const pattern = [2, 5, 1, 2];
    const result = [];
    
    for (let i = 0, patternIndex = 0, toDeleteIndex = pattern[0] - 1; i < arr.length; i++) {
      if (i === toDeleteIndex) {
        patternIndex = (patternIndex + 1) % pattern.length; // 0, 1, 2, 3, 0, 1, 2, 3, ...
        toDeleteIndex += pattern[patternIndex];
      } else {
        result.push(arr[i]);
      }
    }
    
    console.log(result.join(', '));
    // 0, 2, 3, 4, 5, 8, 10, 12, 13, 14, 15, 18, 20, 22, 23, 24, 25, 28, 30, 32, 33, 34, 35, 38, 40, 42, 43, 44, 45, 48
    Такое задумывалось?
    Ответ написан
    Комментировать
  • Почему данный код выдает ошибку?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Внутри скобок создаётся и тут же вызывается функция. (IIFE – immediately invoked functional expression)

    this для функции, объявленной как function определяется в момент её вызова. Если её вызывают будто она свойство объекта, этот объект будет this'ом.

    Внутри скобок function сама по себе, ни к кому не приделана, разве только к Глобальному. В данном случае window. Поэтому там this === window.

    Ну а window это не user. И там нет искомого свойства, скорее всего. Или есть, но неожиданно другое.
    Ответ написан
    Комментировать
  • Как выделить в массиве объектов максимальные и минимальные значения?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно сначала пройти по массиву и собрать минимальные/максимальные значения в объекты-словари типа
    maxValues = { fullPrice: 123, rating: 5 };
    minValues = { fullPrice: 103, rating: 3 };

    А затем второй раз пройтись по исходному массиву, расставляя пропсы min/max/value:
    Решение
    const src = [{ id: 1, fullPrice: 123, rating: 5 }, { id: 2, fullPrice: 103, rating: 3 }];
    
    const checkProps = ['fullPrice', 'rating'];
    
    const xValues = (method, initialValue) =>
      src.reduce((acc, c) => {
        Object.entries(c).forEach(([key, value]) => {
          if (checkProps.includes(key)) {
            acc[key] = Math[method](acc[key], value);
          }
        });
    
        return acc;
      }, Object.fromEntries(checkProps.map(propName => [propName, initialValue])));
    
    const minValues = xValues('min', Number.POSITIVE_INFINITY);
    const maxValues = xValues('max', Number.NEGATIVE_INFINITY);
    
    const result = src.map(item =>
      Object.fromEntries(
        Object.entries(item).map(([key, value]) => {
          if (checkProps.includes(key)) {
            return [key, { value, min: minValues[key] === value, max: maxValues[key] === value }];
          }
          return [key, value];
        })
      )
    );

    Результат:
    [
      {
        "id": 1,
        "fullPrice": {
          "value": 123,
          "min": false,
          "max": true
        },
        "rating": {
          "value": 5,
          "min": false,
          "max": true
        }
      },
      {
        "id": 2,
        "fullPrice": {
          "value": 103,
          "min": true,
          "max": false
        },
        "rating": {
          "value": 3,
          "min": true,
          "max": false
        }
      }
    ]

    Ответ написан
    Комментировать
  • Как дописывать + вместо %20?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Используйте URLSearchParams() — они кодируют пробел в плюс. В отличие от encodeURIComponent()

    (new URLSearchParams({q: 'QnA Habr'})).toString()
    // "q=QnA+Habr"
    Ответ написан
    Комментировать
  • Как проксировать запросы только если хост доступен?

    См. health_check в NGINX
    Это относится к выбору серверов. Поэтому надо будет локальную папку поднять как ещё один "сервер" на левом порте, скажем, 3000.
    Ответ написан
    2 комментария
  • Почему числу внутри setInterval нельзя прибавить другое число?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно так переписать, не меняя смысла:
    function foo(currentNumber){
        console.log(currentNumber);
        currentNumber++;
    }
    
    setInterval(foo, 1000, 5);
    Здесь, наверное, понятно, почему будет каждый раз 5 ?

    Ну, или даже так:
    foo(5); // выведет 5
    foo(5); // выведет 5
    foo(5); // выведет 5
    Внутренняя переменная функции изначально 5, выводит 5 и становится 10. Функция завершила работу, про переменную все забыли.
    Ответ написан
    Комментировать
  • Что надо сделать что бы таймер не сбрасывался при обновлении страницы?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    лучше один раз в начале определить дату-время окончания отсчёта, и её 1 раз сохранить сразу же в LocalStorage.

    По таймеру показывать разницу текущего времени и «времени Че».

    Таймеры не точны. Поэтому лучше зарядить этот таймер не на 1 секунду, а чаще, на 250 мс, например — это поможет избежать иногда проскакивания секунды или, наоборот, чуть более быстрой смены.
    Ответ написан
    Комментировать
  • Как добавить действия новым создаваемым карточкам?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Как исправить готовый код?
    Код надо привести в вопросе, окружив тегом <code>

    Сейчас у вас создаются 6 компонентов и тут же вешаются на них слушатели событий. См. все моменты с addEventListener('click', ...

    Когда создаётся вдруг новый ещё один компонент, на его суб-элементы слушателей клика уже никто не вешает, поэтому «действия» и не работают.

    Лучший вариант решения – слушать событие click выше, на общем родителе всех этих карточек – cardsContainer. Всего один слушатель. В обработчике разбирать, по кому, собственно, кликнули: смотреть класс кликнутого элемента и искать ближайшую к нему карточку.

    Так будут обработаны все карточки внутри этого общего родителя.

    spoiler
    cardsContainer.addEventListener('click', ({ target }) => {
      if (target.classList.contains('element__button')) {
        // toggle Like
        target.classList.toggle('element__button_active');   
      } else if (target.classList.contains('element__basket')) {
        // delete
        target.closest('.element').remove();
      } else if (target.classList.contains('element__item')) {
        // open picture
        openPicture({ target });
      }
    });
    // и убрать всё ставшее ненужным
    Ответ написан
    Комментировать
  • Как изменить массив в usestate?

    Заменять массив целиком на новый. См. документацию (на англ.).

    Если коротко: никаких мутаций. arr[1] = 2; – нельзя.

    function up() {
      const newPosition = catPosition.slice(); // сделали новый массив, копию
      newPosition[1]++;
      setCatPosition(newPosition);
    }
    Ответ написан
    1 комментарий