Ответы пользователя по тегу JavaScript
  • Как преобразовать массив в такой объект?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Надо делать пустой объект и двигаясь по массиву набивать его парами ключ-значение.
    Как только пошёл повтор ключа – это новый объект. Тот заполненный выкидываем в результат, и начинаем заполнять новый пустой.

    var arr = [
        "weather_c",
        "+30",
        "population",
        10000000,
        "city_name",
        "Los angeles",
        "weather_c",
        "+15",
        "population",
        5000000,
        "city_name",
        "Chicago"
      ];
    
    
    var data = {}
    var index = 1;
    var i, key, value;
    var obj = {}
    
    for(i = 1; i < arr.length; i+=2) {
      key = arr[i-1];
      value = arr[i];
      if( obj.hasOwnProperty(key)) {
        data[index.toString()] = Object.assign({}, obj);
        index++;
        obj = {}
      }
      obj[key] = value;
    }
    data[index.toString()] = Object.assign({}, obj);
    
    JSON.stringify(data)
    /*
    {"1": {"weather_c":"+30","population":10000000,"city_name":"Los angeles"},
    "2": {"weather_c":"+15","population":5000000,"city_name":"Chicago"}}
    */
    Ответ написан
    Комментировать
  • Как найти числа фибоначчи в заданном интервале?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Найдите первое число Фибоначчи, попадающее в диапазон, по приближенной формуле, и дальше генерите сложением.

    function fibRange( from, to) {
      if( isNaN(from) || isNaN(to) || from < 2 || from > to) {
        throw "Bad argument(s)";
      }
      
      var root5 = Math.sqrt(5), phi = (1 + root5)/2, logPhi = Math.log(phi);
      var nFrom = Math.ceil( Math.log((from - 0.5) * root5) / logPhi);
      var nTo = Math.floor( Math.log((to+0.5) * root5) / logPhi);
    
      function nthFib(n) {
        return Math.round( (Math.pow(phi, n) - Math.pow( -phi, -n)) / (2 * phi - 1));
      }
      
      var a = nthFib(nFrom);
      var result = [a];
      if( nFrom === nTo) return result;
      var i = nFrom + 1;
      var b = nthFib(i);
      while( i <= nTo) {
        result.push(b);
        b = a + b;
        a = b - a;
        i++;
      }
      
      return result;
    }
    
    
    fibRange(10,377)
    /*
    13,21,34,55,89,144,233,377
    */
    Ответ написан
    Комментировать
  • Как вывести все числа являющиеся произведением простых чисел?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Все, являющиеся произведением – это все, кроме простых.
    Значит, надо получить все числа, кроме простых, в интервале 1..1400.
    Для поиска простых в таком небольшом диапазоне подойдёт алгоритм решета Эратосфена. Чтобы не писать вам целиком готовое решение, вот код, который только получает массив простых чисел от 2 до N:

    function primes(n) {
      var i, j, isPrime = Array(n), result= [];
      for(i=2; i<n; i++) isPrime[i] = true;
      for(i=2; i * i <= n; i++) {
        if( isPrime[i]) {
          for(j = i * i; j <= n; j += i) isPrime[j] = false;
        }
      }
      
      for(i=2; i<n; i++) {
        if(isPrime[i] === true) result.push(i);
      }
      return result;
    }


    Дальше вы уж сами, пожалуйста.
    Ответ написан
    3 комментария
  • Сравнение каждый с каждым?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Понадобится два пальца.

    Один указывает сначала на самый левый элемент. Другой перебирает со следующего и дальше направо:
    ooooooooooo
    ||-->


    Затем левый сдвигаем на один вправо, и всё повторяется: справа от него второй и дальше направо идёт:
    ooooooooooo
     ||-->

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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Кажется, вам подойдёт такой простой алгоритм: перебрать все числа в двоичной записи от 1 до 2n, и брать те элементы строки, которым соответствует 1.

    Набросал функцию, подбирающую из данных элементов комбинацию, дающую наиболее близкую сумму к заданной:
    function nearest(arr, total) {
      var len = arr.length
        , i
        , bit
        , sum
        , n = Math.pow(2, len)
        , currDist
        , index = undefined
        , dist = undefined
        , result = []
      ;
      
      for( i = 1; i < n; i++) {
        sum = 0;
        for( bit = 0; bit < len; bit++) {
          if( i & (1 << bit)) sum += arr[bit];
        }
        
        currDist = Math.abs(total - sum);
        if( typeof dist === 'undefined' || dist > currDist) {
          index = i;
          dist = currDist;
          if( dist === 0) break;
        }
      }
      
      for(bit = 0; bit < len; bit++) {
        if( index & (1 << bit)) result.push(arr[bit]);
      }
      
      return result;  
    }
    
    nearest([1,3,4,6,8], 12) // [1,3,8]
    nearest([1,2,4,6,8], 12) // [2,4,6]
    nearest([7,9,13,19,28], 12) // [13] dist = 1
    nearest([7,9,13,19,28], 28) // [9,19] не [28] т.к. останавливается на первом найденном варианте
    Ответ написан
    Комментировать
  • Что быстрее и лучше map() или foreach() или for() в javascript?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Зачем гадать, если можно измерить. Например.
    Ответ написан
    Комментировать
  • Как работать с состояниями в приложений JavaScript?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Один из вариантов хранить их как битовую карту – одно целое число, где определённый бит что-то значит. В вашем случае первые 5 битов, например, отражают состояние чекбоксов:
    0000 0010
       │ │││┕╼ бит 0, чекбокс 0
       │ ││└── бит 1, чекбокс 1
       │ │└─── бит 2, чекбокс 2
       │ └──── бит 3, чекбокс 3
       └────── бит 4, чекбокс 4


    Так вы сможете чуть быстрее писать условия, напр.
    switch( bitmap) {
      case 0: // все выключены
        // загрузить что-то там
        break;
      case 1<<3: // включен только 3-й бит
        // загрузить что-то для 3-го чекбокса
        break;
      case 28: // вкл. 3, 4 и 5-й
      // ...
    }
    Ответ написан
    2 комментария
  • Функция сортировки массива в js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    в документации на MDN неплохо описано назначение сортировочной функции:
    Если функция сравнения compareFunction предоставлена, элементы массива сортируются в соответствии с её возвращаемым значением. Если сравниваются два элемента a и b, то:

    Если compareFunction(a, b) меньше 0, сортировка поставит a по меньшему индексу, чем b, то есть, a идёт первым.

    Если compareFunction(a, b) вернёт 0, сортировка оставит a и b неизменными по отношению друг к другу, но отсортирует их по отношению ко всем другим элементам. Обратите внимание: стандарт ECMAscript не гарантирует данное поведение, и ему следуют не все браузеры (например, версии Mozilla по крайней мере, до 2003 года).

    Если compareFunction(a, b) больше 0, сортировка поставит b по меньшему индексу, чем a.

    Функция compareFunction(a, b) должна всегда возвращать одинаковое значение для определённой пары элементов a и b. Если будут возвращаться непоследовательные результаты, порядок сортировки будет не определён.
    Ответ написан
    Комментировать
  • Как сконвертировать плоский массив в дерево?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    1. Найти корневой элемент – в вашем случае это с наименьшим id
    2. Далее рекурсивно вызывать функцию, которая получая на вход элемент дописывает ему детей по их id.


    Чтобы быстрее по id находить весь элемент, данные в начале преобразовываются в «словарь» – объект, где свойства это id, а значения элементы.

    var data = [
    {id: 0, name: 'Main', path: '/', childs: [1,2]},
    {id: 1, name: 'One', path: '/one', childs: [3]},
    {id: 2, name: 'Two', path: '/two', childs: []},
    {id: 3, name: 'Three', path: '/one/three', childs: []}
    ];
    
    function makeTree(d) {
      var id, el, i, dict = {}, minId, r;
      
      function parseChildren(el) {
        var i, newEl;
        for( i = 0; i < el.childs.length; i++) {
          newEl = makeElement(dict[ el.childs[i] ]);
          parseChildren( newEl);
          el.children.push( newEl);
        }
        delete el.childs;
      }
      
      for( i = 0; i < d.length; i++) {
        el = d[i];
        id = el.id;
        if( typeof minId === 'undefined' || minId > id) minId = id;
        dict[id] = el;
      }
    
      r = makeElement( dict[minId] ); // root element
      parseChildren(r);
      return r;
    }
    
    function makeElement(arrElement) {
      return {
        name: arrElement.name,
        path: arrElement.path,
        childs: arrElement.childs,
        children: []
      };
    }
    
    var tree = makeTree(data);
    /* {
    	"name": "Main",
    	"path": "/",
    	"children": [{
    		"name": "One",
    		"path": "/one",
    		"children": [{
    			"name": "Three",
    			"path": "/one/three",
    			"children": []
    		}]
    	}, {
    		"name": "Two",
    		"path": "/two",
    		"children": []
    	}]
    } */
    Ответ написан
    Комментировать
  • Как мне добавить к 001 единицу и чтобы стало 002?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    1. найти позицию, с которой начинаются цифры в конце
    2. запомнить длину числа
    3. увеличить на 1 и перевести в строку
    4. при необходимости дописать нулей
    5. склеить с частью до числа
    function stringInc(s) {
      var pos = s.length - 1;
      while(pos >= 0) {
        if( Math.abs(s.charCodeAt(pos) - 52.5) < 5) pos--;
        else break;
      }
      if( ++pos >= s.length) return s; // no number
      var numLength = s.length - pos;
      var numString = (parseInt(s.substr(pos)) + 1).toString();
      if( numString.length < numLength) {
        numString = ((Array(1 + numLength).join('0')) + numString).substr(-numLength);
      }
      
      return s.substr(0,pos) + numString;
    }
    
    stringInc('abc123') // abc124
    stringInc('abc999') // abc1000
    stringInc('abc00009') // abc00010
    stringInc('009') // 010
    stringInc('9') // 10
    stringInc('aaa') // aaa
    Ответ написан
    Комментировать
  • Как правильно распарсить массив?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Создать объект со свойством areas:
    var result = { "areas": "значение для areas"}

    Взять массив из свойства "mh" исходных данных. Это запись в JSON поэтому просто пишем
    peremennaya = {...тут весь этот JSON...}
    peremennaya.mh // тут нужный массив


    Из этого массива нужно сделать новый, где каждый элемент будет содержать только два свойства: id и title. Первое берется из оригинала как есть, а второе нужно составить, собрав значения свойств элемента title и count через пробел-дефис-пробел:
    '' + el.title + ' - ' + el.count

    Когда нужно над каждым элементом массива произвести какое действие, удобен метод массивов map(). В него передаётся функция, которая, получая на вход очередное значение из массива, что-то с ним делает и возвращает новое значение.

    Итого:
    var d = {"mh": [{"id": "BR", "count": 18516, "title": "Brazil"}, 
        {"id": "US", "count": 4514, "title": "United States"}, 
        {"id": "MY", "count": 390, "title": "Malaysia"}, 
        {"id": "IT", "count": 208, "title": "Italy"}]
    };
    
    var result = {areas: d.mh.map(el => ({id:el.id, title:''+el.title+' - '+el.count}))}
    
    // {"areas":[{"id":"BR","title":"Brazil - 18516"},{"id":"US","title":"United States - 4514"},
    //   {"id":"MY","title":"Malaysia - 390"},{"id":"IT","title":"Italy - 208"}]}
    Ответ написан
    Комментировать
  • Как выбрать из текста 3 слова одинаковой или похожей (максимально приближенной) длины?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Собрать из текста словарь "длина": [слово,слово]
    Выбирать слова нужной длины, а при отсутствии смотреть соседние по значению ключи.

    words = txt.replace(/[\.,\?\!\:;\–\(\)]/g, '').toLowerCase().split(/\s+/);
    
    // make dictionary
    var db = [];
    for( var i = 0; i < words.length; i++) {
      word = words[i];
      len = word.length;
      if(db.length <= len || typeof db[len] == 'undefined') db[len] = [];
      if(!~db[len].indexOf(word)) db[len].push(word);
    }
    
    function getWords(db, length, n) {
      n = n || 3;
      var result = [], offset = 0, m;
      length = Math.max(0, Math.min(length, db.length));
      while( result.length < n) {
    
        m = n - result.length;
        if( db[length + offset]) {
          result = result.concat( getUpTo(m, db[length + offset]))
        }
    
        m = n - result.length;
        if( offset &&  m  &&  db[length - offset]) {
          result = result.concat( getUpTo(m, db[length - offset]))
        }
        
        m = n - result.length;
        if( m === 0) break;
        offset++;
        if( offset + length > db.length && offset > length) break;
      }
      
      return result;
    }
    
    function getUpTo(n, arr) {
      return arr.slice(0, Math.min(n, arr.length));
    }


    Fiddle
    Ответ написан
    1 комментарий
  • Как лучше опрашивать состояния элементов?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Т.е. на сервере что-то происходит, о чём надо оповестить клиент, и вы делаете это, опрашивая раз в секунду сервер «есть чё?», причём в несколько параллельных потоков – по каждому айтему.

    Сделайте «конец» api, с которого можно забирать сразу несколько готовых задач. Когда задача на сервере «пропадает», пихайтё её item_id в некий одноразовый массив для выдачи в клиент.

    Так хоть в один всего поток раз в секунду будете опрашивать сервер, и забирать массив с id завершенных.
    Ответ написан
    Комментировать
  • Как реализовать распознавание фотографий на js и нейронных сетях?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Распозначание цифр делается на основе обучения сети немаленьким набором картинок MNIST где каждой нарисованной цифре соответствует её правильное значение.

    На JavaScript возьмите, например, библиотеку ConvnetJS.

    Готовую, обученную на распознавание компьютерной техники по картинкам сеть хотите готовенькую? Вряд ли найдёте.

    Напишите и обучите сами, спарсив какой-нибудь магазин компьютерной техники – там легко сопоставить картинку и соответствующий ей класс устройства. Но набор только продающихся моделей, наверное, маловат. Можно ещё добавить поисковую выдачу Яндекса/Google по картинкам.
    Ответ написан
    Комментировать
  • Не могу понять как правильно задать условие?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    С прицелом на более сложные кейсы предложу генерировать моменты, переключающие расписание, непременно в будущем. Т.е. создаём объект нужной даты-времени из текущего. И накидываем неделю по необходимости.

    Все ключевые моменты в ближайшем будущем. Смотрим, который из них ближе всего. Это определяет то, какой сейчас интервал активен:
    // Два момента, переключающих расписание
    var s18 = getNextMoment( 0, 18); // Sunday 18:00
    var f12 = getNextMoment( 5, 12); // Friday 12:00
    
    function getNextMoment( day, hour) {
      var D = new Date(), dayDiff;
      D.setHours(hour);
      D.setMinutes(0);
      D.setSeconds(0);
      dayDiff = day - D.getDay();
      D.setDate( D.getDate() + dayDiff + ( dayDiff < 0 ? 7 : 0));
      return D;
    }
    
    if( f12 < s18) { // сначала наступит Пятница 12.00
    
      // Режим ожидания
      
    } else { // сначала наступит Воскресенье 18
      
      if( new Date().getHours() < 6) {
        // Ночной
      } else {
        // Дневной
      }
      
    }
    Ответ написан
    2 комментария
  • Какие есть блиотеки для работы с blockchain?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Посмотрите видео (на англ., 39 минут) про построение системы голосования на блокчейн. Научно-популярно разжёванное, с нуля до построения и развёртывания работающего приложения.
    Ответ написан
    Комментировать
  • Как написать условие на проверку пустой переменной JavaScript?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В данном случае, когда id интервала содержит ненулевое целое число, можно так:
    switchInterval && clearInterval(switchInterval);

    или в более читаемом виде
    if( switchInterval) {
      clearInterval(switchInterval);
    }


    Этот способ не подходит, если валидным значением является ноль или false или пустая строка.
    Ответ написан
  • Почему код JavaScript не работает?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Попробуйте так:
    var i, test;
    for( i = 0; i < checkbox.length; i++) {
      if (checkbox[i].checked) {
        test = document.getElementById('slide' + (i+1));
        test  &&  test.click();
      }
    }
    Ответ написан
    Комментировать
  • Как сделать отсчёт времени до определённой даты?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Тут две задачи:
    1. из строки «часы:минуты:секунды» получить объект Date с ближайшим в будущем моментом с этим часом, минутой и секундой;
    2. запустить таймер обратного отсчёта до этой Даты.


    Сделать объект Date на сейчас и его копию. Копии установить час, минуту и секунду из строки. Если получился объект в прошлом, накинуть один дополнительный день.

    Обратный отсчёт – запускать одну и ту же функцию по несколько раз в секунду для плавности отображения времени, т.к. таймеры в JavaScript не точные и если запускать 1 раз в секунду, секунды могут «икать».

    В функции берем текущее время, сравниваем с заданным. Показываем остающиеся часы-минуты-секунды. И вызываем себя же через сколько-то миллисекунд. Если уже наступило целевое время, выводим другой текст и более не вызываем себя.

    Код
    /**
     * Из строки времени в формате HH:MM:SS
     * делает объект Date
     * с ближайшим, после текущего момента, таким временем.
     * @param String строка времени
     * @return Date Object
     */
    function parseTime(s) {
      var now = new Date(), D = new Date(now.getTime()), HMS = s.split(':');
    
      if( HMS.length !== 3) throw({message:"неверный формат времени"});
      
      HMS = HMS.map(function(t){return parseInt(t)}); // перевести строки в целые
      
      D.setHours(HMS[0]);
      D.setMinutes(HMS[1]);
      D.setSeconds(HMS[2]);
      
      if( D < now) D.setDate( D.getDate() + 1);
      
      return D;
    }
    
    /**
     * добивает число нулями до двух позиций.
     *  3 -> 03
     * 13 -> 13
     */
    function pad(n, len, char) {
      var s = n.toString(10);
      char = char || '0';
      len = len || 2;
      if( s.length >= len) return s;
      return (Array(1+len).join(char) + n).slice(-len);
    }
    
    /**
     * Выводит в заданный DOM-элемент время, 
     * оставшееся до даты-времени в объекте toDate
     */
    function countdown( toDate, el) {
      var diff = toDate.getTime() - new Date().getTime()
        , H
        , M
        , S = Math.floor(diff/1000)
      ;
      
      if( S <= 0) { //  время прошло
        el.innerText = "--:--:-- Ой, всё!";
        return;
      }
      
      H = Math.floor(S/3600);
      S = S % 3600;
      M = Math.floor(S/60);
      S = S % 60;
      
      el.innerText = '' +pad(H) +':' +pad(M) +':' +pad(S);
      
      setTimeout( countdown.bind(this, toDate, el), 111);
    }
    
    countdown(
      parseTime('15:00:00'),
      document.querySelector('h1.question__title')
    );

    Если приведённый код выполнить в консоли/скретчпаде на этой странице, вместо заголовка вопроса появится таймер отсчёта.

    Fiddle
    Ответ написан
    Комментировать