• Как наиболее производительно сделать такой список?

    @StockholmSyndrome
    сначала бы привести к более удобной структуре
    spoiler
    const groupedData = data.reduce((acc, {sport, sub}) => {
      const elem = acc.find((item) => item.sport === sport); 
      if (elem) {
        elem.subs.push(sub);
      } else {
        acc.push({
          sport, 
          subs: sub ? [sub] : []
        });
      }
    
      return acc;
    }, []);

    const $ul = $('<ul>', {
      id: 'list'
    }).appendTo('body'); 
    
    const elems = groupedData.map(({sport, subs}) => {
      return `
        <li>${sport}<ul>
            ${subs.map((sub) => `<li>${sub}</li>`).join('')}
          </ul>
        </li>
      `;
    }).join('');
    
    $ul.append(elems);
    Ответ написан
    5 комментариев
  • Сколько стоит час веб-разработчика-фрилансера?

    @deliro
    Ты веcь такой кругом молодец, то знаешь, это знаешь. А теперь представь себе среднестатистический проект, который должен приносить бизнесу деньги. За две недели работы ты едва напишешь хлипкий CRUD для данных, неправильно смаппив бизнес-сущности в объекты ORM, ещё через месяц натянешь какой-то слайдер на jQ, попутно захватив 2мб JS кривых библиотек, а через два заказчик поставит тебе плохую оценку, потому что твой ценник он оплатил не за то, что ему нужно, а потому что ты знаешь монады, которые ему даром не сдались.

    А теперь давай представим простого программиста. Из алгоритмов он с трудом вспоминает сортировку пузырьком, а двусвязный список — предел его знаний о структурах данных, и даже этим списком он пользовался два раза в жизни. Хаскель он никогда не видел в глаза, C++ учил только в школе, вместо этого пишет неэффективный код на PHP. И у него есть опыт. За день он распишет сущности, за второй сделает универсальный CRUD, на третий день поднимет фронт на React'е с SSR. Да, внутренности проекта будут "медленными". Вместо O(logN) что-то будет выполняться за O(N) или даже O(N^2), но всем похер. Пока всё работает на приемлемом уровне — бизнес радуется.

    Кстати, к чему эта поучительная лапша? Я хотел сказать, что всеми этими модными словами можно пугать друзей и преподавателей, но в реальной жизни все алгоритмы уже реализованы, все типы данных уже подобраны оптимально. Знать их полезно для себя (чтобы мозг не атрофировался), но не для работы. Для работы тебе нужны такие навыки как:

    * Оптимальный баланс между говнокодом и идеальным кодом
    * Оптимальный баланс между скоростью разработки и оптимизацией кода
    * Оптимальный баланс между поддерживаемым кодом и костылями
    * Умение использовать те инструменты, с которыми ты работаешь. Опять же, для того, чтобы писать быстро, при этом имея минимальное количество говнокода и обеспечивая максимальную поддерживаемость (в пределах сроков). Например, можешь выкинуть в помойку свой Vim, как бы круто ты себя не чувствовал, разрабатывая в консольном редакторе, если продукты от JetBrains позволят за это же время сделать что-то лучше или чего-то больше
    * Чувство "знаю больше менеджеров". Это то чувство, когда тебе кажется, что "вот эта фича скоро изменится" и надо сделать архитектуру заранее более гибкой. Или "вот эту фичу мы через месяц выпилим" и не надо тратить на неё силы — напиши костыль и через месяц с чистой совестью удали его
    * Знания, как сделать ту или иную фичу. Потому что фичи повторяются (немного видоизменяясь) от проекта к проекту. И если ты сделал что-то за два дня, в следующий раз ты похожее сделаешь за три часа

    Что касается инструментов, выбери любой полноценный фреймворк, который умеет решать 90%+ потребностей "из коробки": Symfony, Django, Laravel

    Всякие "минималистичные" поделия вроде Falcon, Flask (в PHP не знаю, я на питоне пишу) оставь хипстерам. Пусть они говорят: "Мой фалкон такой быстрый, он написан на Cython". Тебя это не должно волновать, потому что бизнес с твоей скоростью разработки уже заработал достаточно денег, чтобы купить ещё десять серверов, пока фалконисты неделю гуглили, как прикрутить миграциии и запустить юнит-тесты на VPSке за пять баксов.
    Ответ написан
    5 комментариев
  • Зачем нужны prototype если все ключи и методы можно задать в конструкторе?

    @Melagomania
    Определять метод в конструкторе = создавать новую копию функции для каждого нового экземпляра класса. Это не есть хорошо: создав 10 экземпляров класса, мы получим 10 одинаковых функций (зачем?).
    Записывая метод в prototype, мы не присваиваем его непосредственно объекту. Метод окажется в свойстве __proto__ созданного экземпляра. Каждый экземпляр нашего класса имеет свойство __proto__ и это свойство у каждого экземпляра ссылается на ОДИН и то тот же объект, в который мы и записали наш метод, используя prtototype. Такми образом, записав функцию func в prototype и потом создав 10 экземпляров класса, мы получим всего ОДНУ функцию func, сохраненную в __proto__. Все созданные объекты будут использовать эту ЕДИНСТВЕННУЮ функцию, хранящуюся в общем месте.
    Вот как-то так.
    Ответ написан
    Комментировать
  • Должен ли фронтенд разработчик уметь верстать (css)?

    @abbrakadabbra
    Фронт-энд разработчик не умеющий верстать, это как сантехник, не умеющий починить кран. CSS - это наверное самое легкое, что есть во фронт-энд, так что учите его, иначе вы не можете претендовать на его звание. Тем более на full-stack.
    Ответ написан
    Комментировать
  • Чем отличаеться promise от обычных коллбэков?

    delphinpro
    @delphinpro Куратор тега JavaScript
    frontend developer
    Не то же самое

    function ajax() {
      return fetch(target, fetchOptions)
        .then((response) => {
          if (!target) throw new Error('Invalid url');
          if (response.ok) return response.json();
          throw new Error(`${response.status} ${response.statusText}`);
        })
        .then((json) => {
            if (json['statusOk']) return json;
            throw new Error(json['message'] || 'Server response was not ok');
        });
    }
    
    ajax(action, { body: formData })
      .then((json) => {
        console.log('RESPONSE', json);
      })
      .catch((error) => {
        console.error(error);
      });


    Мы можем писать сколько угодно зенов, в каждом что-то делать с данными.
    Если в любом месте вылетит ошибка, она будет нормально обработана в кэтче.
    Код при этом линейный, без дикой вложенности.
    С коллбэками вам нужно на каждом этапе отслеживать ошибки и возвращать их. Легко потеряться, что откуда всплыло или где пропало.
    Альтернатива обработки ошибок — трай/кэтч. Но это не работает на асинхронном коде.
    function myFunc(cb){
      var err = true;
      // имитируем асинхронную операцию
      setTimeout(function(){
        cb(err);
      }, 10);
    }
    
    try {
      myFunc(function(err){
        if (err) throw new Error('Oops');
      });
      alert('Всё как бы хорошо!');
    } catch(e) {
      alert(e.message);
    }

    Этот код выведет сообщение 'Всё как бы хорошо!', хотя всё плохо, была ошибка. https://jsfiddle.net/r3zfa4ee/

    С промисами иначе:
    function myFunc(){
      let promise = new Promise((resolve, reject) => {
        let err = true;
      
        // имитируем асинхронную операцию
        setTimeout(() => {
          if (err) {
            reject('Ooops!');
          } else {
            resolve(123);
          }
        }, 10);
      });
      
      return promise;
    }
    
    myFunc()
      .then(data => {
        alert('Всё точно хорошо!');
      })
      .catch(e => {
        alert(e);
      });

    Здесь уже ошибка будет обработана как надо и мы увидим сообщение 'Ooops!' https://jsfiddle.net/43yh8jad/

    Мы можем выполнить промисы последовательно. Мы можем выполнить их параллельно. Мы можем запустить их на параллельное выполнение, но дождаться только первого отработавшего (так называемая promise race). Разумеется всё это можно и без промисов написать, но какая будет разница в объеме кода и в сложности его понимания?

    А еще есть async/await...
    Ответ написан
    Комментировать
  • Как вставлять элементы в список в определенное место, учитывая индекс элемента?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function transfer(from, to) {
      $(from).on('click', 'button', function(e) {
        const $el = $(e.target).parent();
        const index = +$el.data('index');
        const indices = $('li', to).get().map(n => +n.dataset.index);
    
        if (index < indices[0] || !indices.length) {
          $(to).prepend($el);
        } else if (index > indices[indices.length - 1]) {
          $(to).append($el);
        } else {
          $(`${to} [data-index="${indices.filter(n => n < index).pop()}"]`).after($el);
        }
      });
    }
    
    transfer('#parent1', '#parent2');
    transfer('#parent2', '#parent1');
    Ответ написан
    4 комментария
  • На чем лучше сделать подобный сайт?

    azerphoenix
    @azerphoenix
    Java Software Engineer
    А я бы остановился не на CMS, а на CMF. В частности Yii2, Laravel, Symfony
    ВП конечно хорошая система... но весь функционал личного кабинета упирается в плагин WP Recall. Можно конечно самому написать плагин, но смысл делать это.. Берите Yii2 и пишите на нем
    Ответ написан
    1 комментарий
  • На чем лучше сделать подобный сайт?

    @Ambrosian
    На том, на чем ты лучше умеешь - на том и делай.
    То, что ты знаешь лично лучше - это и будет лучшим выбором.
    Ответ написан
    1 комментарий
  • На чем лучше сделать подобный сайт?

    @fastkulob
    Если не знаете то лучше делайте на Wordpress. А если хотите более надёжную систему лучше битрикс.
    Ответ написан
    Комментировать
  • Как построить такой список, получив данные из массива объектов?

    potapchino
    @potapchino
    https://jsfiddle.net/kh2b4Lpz/

    json
    let json = [
      {"location": {
        "country": {
          "name": "Finland"
        },
        "city":"Helsinki"
      }},
      {"location": {
        "country": {
          "name": "Russia",
        },
        "city":"Moscow"
      }},
      {"location": {
        "country": {
          "name": "Russia",
        },
        "city":"Novgorod"
      }},
      {"location": {
        "country": {
          "name": "USA",
        },
        "city":"Boston"
      }},
      {"location": {
        "country": {
          "name": "Russia",
        },
        "city":"Ufa"
      }},
      {"location": {
        "country": {
          "name": "Australia",
        },
        "city":"Sidney"
      }}
    ];
    js
    let wow = {
      db: {},
    
      parse(data) {
        data.forEach(function({location: {country: {name: country}, city}} = node){
          !this.db[country] ? (this.db[country] = {}, this.db[country][city] = true) : this.db[country][city] = true;
        }, this);
        return this;
      },
    
      render() {
        function renderList(data) {
          return `<ul>${renderCountries(data)}</ul>`
        }
    
        function renderCountries(data, html = '') {
          Object.keys(data).forEach(country => html += `<li>${country}<ul>${renderCities(data[country])}</ul></li>`);
          return html;
        }
    
        function renderCities(data, html = '') {
          Object.keys(data).forEach(city => html += `<li>${city}</li>`);
          return html;
        }
        
        return `<ul>${renderList(this.db)}</ul>`;
      }
    };
    
    document.querySelector('body').innerHTML = wow.parse(json).render();

    render
    5b313b60038b8931713914.png
    Ответ написан
    Комментировать
  • Как построить такой список, получив данные из массива объектов?

    kinglostov
    @kinglostov
    просто lostov
    Код
    let arr = 
    [
    	{
    		"location":{
    			"country":{
    				"name":"Finland",
    				"id":"FI"
    			},
    			"city":"Helsinki"
    		}
    	},
    	{
    		"location":{
    			"country":{
    				"name":"England",
    				"id":"FI"
    			},
    			"city":"London"
    		}
    	},
    	{
    		"location":{
    			"country":{
    				"name":"Russian",
    				"id":"RU"
    			},
    			"city":"Moskow"
    		}
    	},
    	{
    		"location":{
    			"country":{
    				"name":"Russian",
    				"id":"RU"
    			},
    			"city":"Saint Petersburg"
    		}
    	},
    	{
    		"location":{
    			"country":{
    				"name":"Russian",
    				"id":"RU"
    			},
    			"city":"Sevastopol"
    		}
    	},
    ];
    let all = [];
    let bool = true;
    for (var i = 0; i < arr.length; i++) {
    	for (var n = 0; n  <= all.length; n++) {
    		if(all.length == 0) all.push({"country":arr[i].location.country.name,"city":[arr[i].location.city]});
    		bool = true;
    		for (var d = 0; d < all.length; d++) {
    			if(all[d].country==arr[i].location.country.name){
    				bool = false;
    				if(all[d].city.indexOf(arr[i].location.city)<0)all[d].city.push(arr[i].location.city);
    			};
    		}
    		if(bool)all.push({"country":arr[i].location.country.name,"city":[arr[i].location.city]});
    	}
    }
    console.log(all)

    знаю много чего смешной но рабочий код вот дебаг
    консоль
    [
        {
            country: 'Finland',
            city: ['Helsinki']
        },
        {
            country: 'England',
            city: ['London']
        },
        {
            country: 'Russian',
            city: ['Moskow', 'Saint Petersburg', 'Sevastopol']
        }
    ]

    Ответ написан
    Комментировать
  • Почему в админке WordPress загружается файл стилей темы?

    Punkie
    @Punkie
    Ну так не грузите стиль в админке - делов то...

    <?php
    if(!is_admin()) { wp_enqueue_style( 'style-theme', get_template_directory_uri() . '/style.min.css', array(), '1.0.0', 'all');
     }
    ?>
    Ответ написан
    1 комментарий
  • Как правильно вставить и стилизовать svg в данном случае?

    @SergeiB
    Вставить svg можно при помощи JQuery-метода load:
    $('.your-svg-container').load('your-svg-file.svg');
    Ответ написан
    2 комментария
  • Как вы подходите к планированию и проектированию?

    zamboga
    @zamboga
    Аналитика данных, BI-аналитика, дашборды
    чтобы реализация проекта прошла без косяков, задержек сроков, недоразумений и прочего? Какие моменты учитываете при планировании, как ставите задачи (технические и организационные)?

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

    UPD. Погуглите еще про метод ФФФ — полезная штука. Например, вот неплохая статья: punksoft.ru/blog/all/fff
    Ответ написан
    Комментировать
  • Как подключить svg в переменную Pug?

    kreotech
    @kreotech
    Абстрактно-ориентированный программист
    Приветствую.
    Если я правильно понял описанную проблему, у вас происходит вывод экранированной строки. Где все HTML теги превращаются просто в текстовые символы, а не в управляющие.

    Это поведение Pug действует по умолчанию и служит для обеспечения безопасности при возможном использовании этого шаблонизатора на продакшене.

    Чтобы избежать такого поведения надо использовать вместо вашего варианта, такой:
    li(class= classname + 'item')!= item

    Обратите внимание на восклицательный знак перед знаком "равно".
    Ответ написан
    1 комментарий
  • Как сделать эффект прозрачности, привязанный к скроллу?

    @levchak0910
    answer.correct ? press({correct: true}) : next()
    Берите высоту этого элемента, "высоту" скролла, небольшие математические операции и готово.
    Так как высота Вашего элемента всегда равна высоте окна браузера можно использовать screen.availHeight
    let element = document.querySelector("Ваш элемент");
    document.onscroll = () => {
        let percent = ( screen.availHeight - window.pageYOffset / 2 ) / screen.availHeight;
        if(percent <= 0) element.style.opacity = 0;
        else element.style.opacity = percent;
        console.log(percent);
    };

    На счет производительности посмотрите Debounce
    Ответ написан
    Комментировать
  • Каким регулярным выражением можно обрезать подобную строку?

    mashletov
    @mashletov
    Math.random()
    var url = 'ваш url';
    var result = url.match(/^https?:\/\/(?:[^\/])+/i);
    
    console.log(result[0]);
    Ответ написан
    Комментировать