• Как работает функция изменения положения элемента в массиве?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Чтобы поменять местами, надо:
    1. выдернуть первый,
    2. выдернуть второй,
    3. вставить на новое место первый,
    4. вставить на новое место второй.

    Метод массива .splice() умеет и выдирать и вставлять одновременно. Его аргументы:
    позиция-из-которой, сколько-выдрать, вставить-этого, вставить-ещё, ...
    А возвращает он массив выдранных. Поэтому [0] вернёт первый выдранный элемент.

    Можно расписать вашу функцию подробнее:
    function swap(arr, from, to) {
      // выдёргиваем:
      const A = arr.splice(from, 1)[0];
      const B = arr.splice(to-1, 1)[0]; 
      // -1 т.к. массив стал короче после первой операции
    
      // вставляем
      arr.splice(from, 0, B); // 0 - ничего не вырезаем, только вставляем
      arr.splice(to, 0, A);
    }

    Ещё проще то же выглядит безо всяких splice()
    function swap(arr, from, to) {
      // выдёргиваем-копируем:
      const A = arr[from];
      const B = arr[to]; 
    
      // вставляем-заменяем
      arr[from] = B;
      arr[to] = A;
    }
    Ответ написан
  • Как не нанять токсичного сотрудника?

    Такие сотрудники тоже нужны и в чём-то незаменимы.

    5df12d35a1b02636101231.jpeg
    Ответ написан
  • Как создать матрицу смежности на основе 2D карты?

    Поскольку «порталов» не предусмотрено, в любую ячейку можно попасть максимум из 4-х соседних.

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

    Не пользуюсь разбиением экрана.

    Удобны множественные рабочие столы на каждом из мониторов, и смахивание тремя пальцами между ними.
    Вместо мышки/трекболла давно использую только Magic Trackpad, поэтому пальцевые жесты предпочтительны.
    Ответ написан
  • Как найти и изменить динамический элемент в Javascript?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    MutationObserver позволяет следить за изменениями DOM.

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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Предложу свой велосипед на костылях. Без сортировки!
    const zip = arr => arr
      .reduce((agg, c) => {
        const iR = agg.indexOf(c + 1);
        const iL = agg.lastIndexOf(c - 1);
        if (!!~iR && !!~iL) agg.splice(iL, 2); // закрыли дырку
        else if (!!~iR) agg[iR] = c; // сдвинули границу
        else if (!!~iL) agg[iL] = c; // то же
        else { // вставляем сироту - найти позицию сразу после меньшего
          let pos = 0;
          while (pos < agg.length  &&  agg[pos] < c) pos++;
          agg.splice(pos, 0, c, c); // вставляем дважды
        }
        return agg;
      }, [])
      .reduce((agg, c, i, arr) => {
        if (!(i&1)) agg.push(arr[i+1] === c ? c : [c, arr[i+1]].join('-'));
        return agg;
      }, [])
      .join(', ')
    ;

    Массив границ диапазонов, в нём всегда чётное число элементов.
    Очередное число вставляем в массив: ищем, есть ли его ближайшие соседи слева и справа.
    • Если есть оба, число закрывает «дырку», надо просто убрать этих двух соседей.
    • Если нашёлся только один – заменяем его собой, сдвигая границу.
    • Если ни одного соседа, значит, число пока сирота, вставляем его дважды,
      как будто это и левая и правая граница диапазона.
    Так из первого примера получается [ 0, 5, 8, 9, 11, 11 ]
    Остаётся форматирование. Смотрим только чётные элементы. Если текущий и следующий элементы равны, это «одинокое» число. Если не равны — это диапазон через дефис. И склеиваем через запятую-с-пробелом.

    Учитывая сортированность собираемого массива, можно ускорить, заменив indexOf() и lastIndexOf() на самописный поиск, останавливающийся на элементе, бОльшем или меньшем искомого.

    Fiddle с тестами

    Ответ написан
  • Какую идею реализовать в навыках Алисы?

    «Быки и коровы» в Алисе реализованы в простейшем детском варианте. Сделайте «взрослый» вариант, где загадывается 5-буквенное слово.
    Ответ написан
  • Как во Vue правильно сделать роут только для development-режима?

    Предлагаю такой костыль способ:

    router.js
    const routes = [
      { path: '/foo', component: Foo },
      { path: '/bar', component: Bar, isDevOnly: true },
      { path: '*', component: Baz },
    ]
    
    const router = new VueRouter({
      routes: routes.filter(r => DEVELOPMENT || !r.isDevOnly)
    })


    При сборке назначать эту константу DEVELOPMENT из переменной окружения с помощью DefinePlugin

    webpack.common.js
    const webpack = require('webpack');
    
    module.exports = {
      // ...
      plugins: [
        new webpack.DefinePlugin({
          DEVELOPMENT: JSON.stringify(process.env.mode === 'development'),
        }
      ]
    Ответ написан
  • Объясните в чем тут проблема?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Пользуйтесь консолью – это бесплатно, спортивно, современно!
    console.log(this); // window
    В вашем коде this не принимает значение кнопки, а наследует его из внешнего кода. В данном случае, глобального, поэтому this === window

    Вероятно, вы ожидали, что this будет нажатой кнопкой. Так бы работало без стрелочной функции, если по-старинке передавали function(evt) {}
    Ответ написан
  • Как получить access_token с правом app_widget?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Виджеты сообществ — документация
    0. Получение ключа доступа
    Для работы с виджетами в сообществе необходимо получить токен сообщества с правом доступа app_widget при помощи события VK Connect: VKWebAppGetCommunityAuthToken в приложении с типом VK Mini Apps.


    Создайте приложение ВК типа VK Mini Apps.

    Понадобится библиотека VK Connect: npm install @vkontakte/vk-connect

    И что-то вроде такого в index.js:
    import connect from '@vkontakte/vk-connect'; 
    
    // Sending event to client
    connect
      .sendPromise('VKWebAppGetCommunityAuthToken', {
        "app_id": 6909581, // id вашего свежесозданного mini App
        "group_id": 1,  // id группы, где вы админ, куда виджет
        "scope": "app_widget"
      })
      .then(data => {
        // Обработка события в случае успеха
        console.log(data);
      })
      .catch(error => {
        //Обработка событияв случае ошибки
      });
    Затем, наверное, webpack'ом билдится готовый скрипт, который подгружается в браузер.

    При этом сам токен вы не получаете, не сохраняете, не копируете. Просто теперь у этого VK Mini App'а вашего есть права на обновление кода виджета в вашем сообществе.
    Ответ написан
  • Как проверить находится ли пользователь на открытой вкладке?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Есть Page Visibility API (на англ.)

    Оттуда пример кода, который приостанавливает воспроизведение видео, если таб стал неактивным:
    spoiler
    // Set the name of the hidden property and the change event for visibility
    var hidden, visibilityChange; 
    if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support 
      hidden = "hidden";
      visibilityChange = "visibilitychange";
    } else if (typeof document.msHidden !== "undefined") {
      hidden = "msHidden";
      visibilityChange = "msvisibilitychange";
    } else if (typeof document.webkitHidden !== "undefined") {
      hidden = "webkitHidden";
      visibilityChange = "webkitvisibilitychange";
    }
     
    var videoElement = document.getElementById("videoElement");
    
    // If the page is hidden, pause the video;
    // if the page is shown, play the video
    function handleVisibilityChange() {
      if (document[hidden]) {
        videoElement.pause();
      } else {
        videoElement.play();
      }
    }
    
    // Warn if the browser doesn't support addEventListener or the Page Visibility API
    if (typeof document.addEventListener === "undefined" || hidden === undefined) {
      console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
    } else {
      // Handle page visibility change   
      document.addEventListener(visibilityChange, handleVisibilityChange, false);
        
      // When the video pauses, set the title.
      // This shows the paused
      videoElement.addEventListener("pause", function(){
        document.title = 'Paused';
      }, false);
        
      // When the video plays, set the title.
      videoElement.addEventListener("play", function(){
        document.title = 'Playing'; 
      }, false);
    
    }
    Ответ написан
  • Как в гугл таблице скопировать данные из одного листа в другой?

    Можно использовать метод Range.copyTo()

    function myFunction() {
      var sourceSheet = SpreadsheetApp.getActiveSpreadsheet(); //лист откуда берем данные
      var activeRow = list1.getActiveSheet().getActiveCell().getRow(); //номер активной ячейки
    
      var destSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Журнал ввода данных");
      var lastRow = destSheet.getLastRow();
      destSheet.insertRowAfter(lastRow);
      var destRow = lastRow + 1;
      
      function copyCell(colFrom, colTo) {
        sourceSheet.getRange(activeRow, colFrom).copyTo(destSheet.getRange(destRow, colTo));
      }
                                                                                                          
      copyCell(1, 1); // номер участка
      copyCell(2, 2); // имя человека
      copyCell(4, 3); // дата начала работ
      copyCell(6, 4); // дата завершения работ
    }


    Добавить вызов этой функции в собственное доп. меню, можно так:
    function onOpen(e) {
      SpreadsheetApp.getUi()
          .createMenu('Работа с Журналом')
          .addItem('Копировать в журнал', 'myFunction')
          .addToUi();
    }
    Ответ написан
  • Три игральные кости подбрасывают по одному разу. которая вероятность того, что при этом все числа на трех гранях будут разными?

    Можно нарисовать дерево вариантов:
    5de56ffb5a740263340270.png

    1. A – первый бросок, тут устроит любой вариант из 6, поэтому 6/6
    2. B – второй бросок. Тут не подойдёт вариант, совпадающий с выпавшим в А. 1/6 отваливается, остаётся 5/6
    3. C или D – третий бросок (наш - C) Тут из 6 вариантов устроят только 4. 4/6


    Остаётся перемножить:
    6/6 * 5/6 * 4/6 = 120/216 = 5/9
    Ответ написан
  • Nginx вынести страницу на поддомен?

    server {
      server_name catalog.site1.ru;
      location / {
        pro xy_pass http://site1.ru/catalog?date_from=&date_to=;
      }
    }

    Подробнее см. Модуль ngx_http_pro xy_module

    (Тостер режет любые упоминания про кси, поэтому с пробелами)
    Ответ написан
  • Становится ли контейнер образом?

    1. верно
    2. ок
    3. нет. docker build (док) создаёт новый image (образ) В вашем примере с тегом python-barcode
    4. docker run запускает из образа контейнер. Можно и не один, а несколько, даже параллельно. В вашем примере имя для него сгенерится автоматом, какая-нибудь смешная комбинация двух слов. Контейнер может работать, останавливаться, перезапускаться. Можно удалить контейнер. Контейнер не изменяет образ, из которого создан – он «накатывает» свою деятельность поверх, в новых слоях.
    5. контейнером не поделиться. Делятся образом. Если в контейнер вносили изменения - например, зашли в него терминалом, установили доп. пакеты – можно из этого контейнера создать новый image через docker commit


    базовый FROM образ -- образ с доп. слоями = ваш новый образ -- контейнер и изменения -- образ с изменениями
    Ответ написан
  • Как связать несколько сайтов к одному IP?

    Все запросы должен ловить единый сервер, например, nginx.
    По заголовкам запросов Host: ... перенаправлять/проксировать запрос на соотв. виртуальный сервер.

    server {
      server_name site.ru;
      location / {
            proxy_pass http://127.0.0.1:8000; # допустим, тут слушает основной
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            # ... ещё инструкции - передача заголовков, кэширование..
        }
    }
    
    server {
      server_name name1.site.ru;
      location / {
          proxy_pass http://127.0.0.1:8001; # вирт-1
          # ...
      }
    }
    
    server {
      server_name name2.site.ru;
      location / {
          proxy_pass http://127.0.0.1:8002; # вирт-2
          # ...
      }
    }
    Ответ написан
  • Где найти энтузиастов в разработке интересных проектов?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    По сути вы вампир, которому нужны жертвы. Это нормально. Проще их уболтать, обмануть укусить, увлечь в оффлайне: личной харизмой, обаянием и жестикуляцией с легким алкоголем. Так вероятнее получится собрать небольшую секту своих апостолов и дойти до скорой Голгофы. Ну, или первого раунда.

    Оффлайн зазнакомиться с целевой аудиторией можно на местных митапах по теме.
    Ответ написан
  • Как в docker работать с несколькими проектами?

    все на php7.3, mysql 5.7, nginx

    Раз у всех проектов одна среда, достаточно запустить по одному инстансу php-fpm, mysql, nginx и пользоваться ими из всех разрабатываемых проектов.

    «Проект», получается, это папка с файлами, отдельная бд или таблицы на общем сервере MySQL, и прописанный в конфигах nginx
    location /project-42 { root /projects/project-42; ... }
    
    ### или целый блок
    
    server {
      listen 80;
      server_name  project42.dev;
      ... 
    }


    Пожалуй, лучше работать через docker-compose: весь конфиг в одном файле, общая сеть, сервисы друг друга видят.

    Поднимите сначала один из проектов. Потом разберитесь, как добавить файлы остальных через volumes:
    nginx:
      volumes:
        - "/freelance/projects/Project-0/:/var/www/project0"
        - "/freelance/projects/Project-42/:/var/www/project42"
        # ...
    php-fpm:
      volumes:
        # то же самое сюда


    2) Как проектам дать не localhost:8080, а нормальный урл типа project.dev?

    В конфиге сервиса nginx в docker-compose.yml пропишите вместо 8080:8080:80, а в локальном файле hosts допишите 127.0.0.1 project.dev project42.dev
    Ответ написан
  • Как узнать элемент с которого начинаются цифры в массиве?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вот такая колбаса вернёт массив, где только «правильные» числа:
    [10, 20, 30, 50, 235, 3000].filter(n => !!~[1,2,5].indexOf(+n.toString()[0]))
    // результат  [ 10, 20, 50, 235 ]
    Вывод на экран пилите самостоятельно.

    Метод массива filter() оставит только те элементы, для которых функция внутри вернёт true. Функция аргумент (в скобках) применяется по очереди к каждому элементу массива (числу).
    Переводит число в строку, забирает первй символ (первую цифру) и переводит опять в число (оператор +).
    indexOf() ищет полученную первую цифру в массиве допустимых: 1, 2, 5 и возврашает его индекс (0, 1 или 2) или -1, если не найдено.
    Битовое инвертирование ~ из -1 сделает 0. А из любого другого числа (из 0, 1 или 2) – сделает ненулевое число. Два !! это два булевых оператора отрицания. Из аргумента делают true или false. Из 0 получится false, из любого другого true. Таким образом связка !!~ и indexOf() даёт ответ на вопрос найден или не найден?
    Ответ написан
  • Как получить индексы выделенной подстроки?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    См. как работать с Selection API.

    Метод getRangeAt() вернёт диапазон Range. Выделенных фрагментов может быть и несколько, но в вашем примере понадеемся на единственный getRangeAt(0)

    У объекта диапазона Range есть свойства startOffset и endOffset – то, про что спрашиваете.

    Ответ написан