Задать вопрос
  • Как при помощи JS cделать?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Возможно, задача покажется проще, если из первых двух массивов сделать "словари", где ключи id, а значения name.

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

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Посты лайкаются и смотрятся неравномерно: бурлят свежие посты, статично висят старые-забытые.
    Поэтому для кипящего ядра можно держать данные в оперативке, скажем, в Redis – туда писать, оттуда читать. Если ключа поста нет в Redis, то вынимать из БД. Периодически из Redis'а копировать в БД все данные и убирать из Redis данные по постам, которые перестали обновляться.

    Часть нагрузки можно передать на клиент. При загрузке с сервера всем раздавать одинаковые данные о свежих постах (их id без содержания, если длинные). Далее по мере просмотра счётчики лайков/просмотров обновлять на клиенте, синхронизируя лайки с сервером не так часто. И скрипт на клиенте решает дальше, какие посты подгружать и показывать, учитывая локальные просмотры.

    Ещё мысль: nginx умеет Lua. Можно операции с лайками/просмотрами поручить сольному nginx без PHP. Правда, возникает вопрос с авторизацией.
    Ответ написан
    2 комментария
  • Как в ffmpeg из нескольких изображений и их зум склеить видео?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Всё описанное можно сделать в ffmpeg.

    Анимированный зум делается фильтром zoompan. Он с только целыми координатами работает, поэтому, чтобы не дергался, делать это в повышенном разрешении. Потом даунсэмплить.

    Например, из недавнего проекта, где интерактивно генерилась анимация по шаблону, это из bash-скрипта:
    FILTER="[0]                                                   \
        pad=color=0x99999900:w=${wIn}:h=${hIn}:x=${xPad}:y=${yPad}, \
        scale=20064x3264,                                           \
        zoompan=                                                    \
          s=${wSrc}x${hSrc}                                         \
          :d=${frames}                                              \
          :z='( ${zoomcode} ) / 16.89999'                           \
          :x='2*(${xPad} + ${xPoi}) * (zoom - 1) / zoom'            \
          :y='2*(${yPad} + ${yPoi}) * (zoom - 1) / zoom'            \
          [fg];                                                     \
          [1][fg]overlay=x=247:y=438                                \
      "

    Т.к. зумить меньше, чем влезает во вьюпорт нельзя, сначала картинке добавляется по краям паддинг прозрачный, чтобы можно было уменьшать. Потом размер увеличивается с запасом раз в 5-10, чтобы сделать незаметными целочисленные пиксельные шаги зума и смещения.
    Ответ написан
    Комментировать
  • Можно ли этот пример упростить до одного регулярного выражения?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Регулярные выражения «под капотом» не так легки, как выглядят. Там те же циклы, память.

    Данную задачу можно решить посимвольным чтением с занесением открывающих скобок в буфер FILO (First In - Last Out, Первым вошёл, последним вышел). И изъятием из буфера, с хвоста, закрывающих. До первой ошибки или до конца строки. В любой момент открывающая скобка ОК, пушится в буфер. Закрывающая ОК только, если соотв. ей открывающая – последняя в буфере. И в конце убедиться, что буфер пуст - каждой открытой нашлась пара.

    Решение, тесты проходит
    function verify(text) {
      const buffer = [];
      const valid = '()[]{}';
    
      for (let i = 0, len = text.length; i < len; i++) {
        const c = text[i];
        const idx = valid.indexOf(c);
        if (-1 === idx) continue; // не скобка
        if (idx & 1) { // закрывающая (нечет)
          if (0 === buffer.length) return false;
          if (valid.indexOf(buffer.pop()) + 1 !== idx) return false;
        } else { // открывающая
          buffer.push(c);
        }
      }
      
      return buffer.length === 0;  
    }

    Тесты
    (()=>{
    const tests = [
      ["a(b)", true         ],
      ["[{}]", true         ],
      ["[(]", false         ],
      ["}{", false          ],
      ["z([{}-()]{a})", true],
      ["", true             ],
      ["(((}", false        ],
    ];
    
    return JSON.stringify(
      tests.map(t => (verify(t[0]) === t[1] ? 'OK' : 'FAIL' ) + ': ' + t[0])
      , null,  
      2
    );
    })()
    
    
    /*
    [
      "OK: a(b)",
      "OK: [{}]",
      "OK: [(]",
      "OK: }{",
      "OK: z([{}-()]{a})",
      "OK: ",
      "OK: (((}"
    ]
    */
    Ответ написан
  • Как правильно выводить шаблон js через цикл?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    1. в приведённом фрагменте отсутствует метод appendChild(), упомянутый в ошибке.
    2. innerText это не метод, а свойство.
    3. чтобы в цикле не перезаписывались, а накапливались элементы, надо складывать.

    .then(function(result) {
      const el = document.querySelector('.response');
      let html = ''; // здесь соберём html всех блоков из цикла
      for(let i = 0, len = result.data.length; i < len; i++){
        const data = result.data[i];
        html += ` ... <img src="${data.logo}"> ... `;
      }
      el.innerHTML = html;
    })
    Ответ написан
    2 комментария
  • Как правильно добавить токен в Fetch Api?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Документация по fetch и Headers

    Рабочий код в браузере требует same origin
    const token = 'xxxxxx';
    var myHeaders = new Headers();
    myHeaders.append('x-access-token', token);
    
    var myInit = { method: 'GET',
                   headers: myHeaders,
                   mode: 'cors',
                   cache: 'default' };
    
    var myRequest = new Request('http://api.travelpayouts.com/v2/prices/latest', myInit);
    
    fetch(myRequest)
      .then(res => res.json())
      .then(data => console.log(data))
    Но в вашем случае ничего не получится из-за требования Same Origin: через JS в браузере что-то загружать с того сайта можно только страницам, загруженным с него же. Гуглите CORS. Или работайте через nodejs.

    Рабочий код под nodejs
    const http = require("http");
    
    const token = '321d6a221f8926b5ec41ae89a3b2ae7b';
    const url = 'http://api.travelpayouts.com/v2/prices/latest';
    
    http.get(
      url,
      {
          headers: {
          'x-access-token': token
          }
      },
      (res) => {
        const { statusCode } = res;
        const contentType = res.headers['content-type'];
      
        let error;
        if (statusCode !== 200) {
          error = new Error('Request Failed.\n' +
                            `Status Code: ${statusCode}`);
        } else if (!/^application\/json/.test(contentType)) {
          error = new Error('Invalid content-type.\n' +
                            `Expected application/json but received ${contentType}`);
        }
        if (error) {
          console.error(error.message);
          // Consume response data to free up memory
          res.resume();
          return;
        }
      
        res.setEncoding('utf8');
        let rawData = '';
        res.on('data', (chunk) => { rawData += chunk; });
        res.on('end', () => {
          try {
            console.log("raw data:", rawData);
            
            const parsedData = JSON.parse(rawData);
            console.log(parsedData);
          } catch (e) {
            console.error(e.message);
          }
        });
      }
      
    ).on('error', (e) => {
      console.error(`Got error: ${e.message}`);
    });
    Ответ написан
  • Как вывести данные из unixtime?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Unix time это целое число секунд с начала эпохи Unix, 1 января 1970.
    В JavaScript время считается не в секундах, а в миллисекундах (1/1000 секунды). Поэтому надо будет домножить на 1e3. Это время можно передать единственным параметром в конструктор объекта Date:
    var vkApiResponse = {
      "response": 1467726682
    };
    
    
    var D = new Date(vkApiResponse.response * 1000);
    D.toString() // Tue Jul 05 2016 16:51:22 GMT+0300 (Moscow Standard Time)
    Ответ написан
    Комментировать
  • Как показать ссылку только 5 пользователям за раз?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Можно сделать JS, который от каждого пользователя будет пинговать ваш сервер раз в N секунд, подтверждая, что пользователь всё ещё на сайте. Прекращение поступления пинга с id отображаемого у того пользователя баннера делает такой баннер вакантным для нового отображения.

    На бэкенде в момент загрузки страницы определяется, какой из вакантных баннеров можно показать.
    Ответ написан
  • Простейший калькулятор на js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    prompt() возвращает String, который надо привести к числу.
    Условие прекращения цикла возможно, не то, что вам на деле требуется, я бы ограничил число итераций:
    var a = +prompt('summa'), i = 0;
    for ( ; ++i<5; a *= 1.012) {
      console.log(`${i}: ${a}`); // смотрим в консоль
    }
    // ввёл 200
    // получилось:
    /*
    1: 200
    2: 202.4
    3: 204.8288
    4: 207.28674560000002
    */


    Ну и вспоминаем математику. Тут идёт умножение числа a на 1.012n раз. Сразу можно посчитать как 1.012 в степени n. Обратная задача - логарифм. Например, как узнать, сколько раз надо умножить на 1.012 сумму 20, чтобы получить 30:Math.log(30/20) / Math.log(1.012) // 33.991
    Ответ написан
  • Сортировка по N значений?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    может, просто слепить значения в строку и сортировать по строке?
    $tosort = array_map(
      function($el) {
        $el['sortable'] = implode(',', [$el['sort_0'], $el['sort_1'], $el['sort_2'], $el['sort_3']]);
        return $el;
      },
      $products
    );
    
    $result = usort(
      tosort,
      function( $a, $b) {
        return $a.sortable < $b.sortable ? -1 : 1;
      }
    );


    p.s. Как «прекрасен» PHP, посмотри:

    Как раз в этом коде понадобились два метода для работы с массивами, и у одного
    array_map() аргументом сначала идёт callable, потом массив;
    а у другого
    usort() наоборот: сначала массив, потом callable.
    ¯\_(ツ)_/¯
    Ответ написан
  • Как сделать отсчет времени в PHP?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Вероятно, можно вычислять время получения очередного бонуса, или даже сколько бонусов должно быть у человека в любой момент времени.

    Например, 1 бонус полагается каждые 15 минут с момента первого визита. Надо запомнить в БД id пользователя и время его первого визита. Тогда при любом следующем его обращении к боту можно посчитать, сколько у того бонусов. Текущее время минус время 1-го визита (в сек.) разделить на 900 и взять целую часть.
    Ответ написан
    3 комментария
  • Как понять синтаксис ES6?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Стрелочные функции это лаконичная запись функций и небольшие отличия с контекстом.
    arr.filter( (num) => num > 0 && num % parseInt(num) === 0 )
    
    // то же, что
    arr.filter( function(num) { return   num > 0 && num % parseInt(num) === 0 ;}  )

    Оставляет только те элементы массива, которые больше нуля И остаток деления (%) на целое значение себя же равен нулю. Т.е. являются квадратами целого.
    Ответ написан
  • Необходим ли здесь Symbol?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Без использования символа переменная handlers имеет значение undefined, которое тоже можно использовать как свойство объекта.
    const a = {};
    let b;
    a[b] = "test";
    
    JSON.stringify(a)
    // "{\"undefined\":\"test\"}"
    
    a[undefined] // "test"
    Ответ написан
    Комментировать
  • Как вызвать код функции?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Оберните код функции и вставьте его сразу в документ, не надо AJAX:
    const mySuperAnimationFunction = () => {
    
    // тут весь "код функции"
    
    }

    И когда нужно выполнить анимацию - доскроллили до места - вызывайте её: mySuperAnimationFunction();
    Ответ написан
    Комментировать
  • Как настроить таймер на javascript - время до открытия магазина?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно всё считать в локальной временной зоне. Известно смещение от UTC времени магазина. Текущее смещение посетителя от UTC получаем через getTimezoneOffset().

    Задача получить два объекта времени: открытия и закрытия магазина, во временной зоне браузера посетителя.

    Если какой-то из двух оказался в прошлом, добавляем ему один день, чтобы оба оказались в будущем. Который из двух оказался меньше – подскажет, открыт сейчас магазин или закрыт.

    Решение
    function tillItOpens() {
      const D = new Date();
      const shopOffsetMin = 5 * 60; // GMT+5
      const myOffsetMin = D.getTimezoneOffset();
      const diffMin = shopOffsetMin + myOffsetMin;
      
    
      function futureDate(hours, fixMin) {
        const d = new Date();
        d.setHours(hours);
        d.setMinutes(0 + fixMin);
        d.setSeconds(0, 0);
        if (d < new Date()) d.setDate(d.getDate() + 1);
        return d;
      }
    
      
      const dOpens = futureDate(9, diffMin);
      const dCloses = futureDate(21, diffMin);
    
      if (dOpens < dCloses) {
        // скоро откроется
        const hours = Math.floor((dOpens - D) / 36e5);
        const minutes = Math.floor((dOpens - D) / 6e4) - 60 * hours;
        
        return `до открытия ${hours}:${minutes}`
        
      } else {
        // сейчас открыто
        return "Сейчас открыто!";
        // хорошо ещё посмотреть, сколько остаётся до закрытия - успеет ли чел.
        // ближайшее закрытие – объект dCloses
      }
    }

    Если сейчас закрыт, запускайте таймер обратного отсчёта до объекта dOpens – он означает время открытия в текущей таймзоне.
    Ответ написан
    3 комментария
  • Как написать скрипт на PHP?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    sscanf()

    $str = '921205400655';
    list($year, $month, $day) = sscanf($str, "%2d%2d%2d");
    if ($year > 30) $year = 1900 + $year;
    else $year = 2000 + $year;
    $date = sprintf("%04d.%02d.%02d", $year, $month, $day);
    
    echo $date; // 1992.12.05
    Ответ написан
    6 комментариев
  • Почему код не работает?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Пишите не через точку, а так примерно:
    json['1 Часть'].t13[0]

    См. доступ к свойствам объекта.
    Ответ написан
  • Как проверить установку node.js на macOS?

    Может, терминал запущен до того, как установили, и не перечитал стартовые скрипты, где дописывается в PATH папка с node.

    1. Попробуйте в новом окне терминала node -v
    2. Наберите echo $PATH
    Ответ написан
    2 комментария
  • Получить по паре одинаковых случайных элементов массива?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Каждому четному индексу N соотв. такой же цвет с индексом N+1

    Возьмем случайное целое от 0 до половины длины, умножим на 2 и вуаля: это индекс первого. Плюс 1 это индекс второго.

    var idxA = 2 * Math.floor(Math.random() * colorsArray.length / 2);
    var idxB = idxA + 1;
    Ответ написан
    Комментировать
  • Как научиться рисовать на граф.планшете?

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

    Как научиться рисовать – думаю, полно уроков на YouTube, поищите те, где они выстроены в серию из нескольких видео от простого к сложному. Хороши и оффлайн курсы, где бумага, карандаш, ластик.
    Ответ написан