function getWinner(points) {
const [ a, b ] = points.reduce((acc, n) => (
n.split('-').forEach((m, i) => acc[i] += +m),
acc
), [ 0, 0 ]);
return a === b
? undefined
: a < b ? 2 : 1;
}const getWinner = points =>
[ 2, , 1 ][-~Math.sign(eval(points.join('+')))];
pre вместо div)white-space: pre;
font-family: monospace;JSON.stringify, и почитайте. При чтении обратите внимание на то, что параметров у него больше одного.
const buttonSelector = 'input[name="group"]';
const contentSelector = '.click';
const activeClass = 'show';// делегирование, обработчик события добавляем один раз, на документ;
// соответствие между радиокнопками и блоками устанавливаем через равенство атрибутов
document.addEventListener('change', ({ target: t }) => {
if (t.matches(buttonSelector)) {
document.querySelectorAll(contentSelector).forEach(n => {
n.classList.toggle(activeClass, n.dataset.click === t.id);
});
}
});
// или, назначаем обработчик события каждой кнопке индивидуально;
// соответствие между радиокнопками и блоками устанавливаем через равенство индексов
const buttons = document.querySelectorAll(buttonSelector);
const contents = document.querySelectorAll(contentSelector);
const onChange = ({ target: t }) =>
buttons.forEach((n, i) => contents[i].classList.toggle(activeClass, n === t));
buttons.forEach(n => n.addEventListener('change', onChange));
Object.values(data.reduce((acc, n) => {
(acc[n.code] ||= {
code: n.code,
name: n.name,
variants: [],
}).variants.push(n);
return acc;
}, {}))
function xxx(arr, num) {
let index = -1;
return () => num * arr[index = (index + 1) % arr.length];
}
const f = xxx([ 5, 6, 9 ], 2);
console.log([...Array(10)].map(f)); // [10, 12, 18, 10, 12, 18, 10, 12, 18, 10]код до вложенной функции менять нельзя
То есть засовывать переменные в массив нечестно
function xxx(num) {
let a = 5;
let b = 6;
let c = 9;
return () => num * ([ a, b, c ] = [ b, c, a ])[2];
// или
return () => num * (t => (a = b, b = c, c = t))(a);
// или
return function() {
return num * this[0][++this[1] % this[0].length];
}.bind([ [ a, b, c ], -1 ]);
// или
return (iter => () => num * iter.next().value)((function*() {
for (;; yield a, yield b, yield c) ;
})());
// или
return (i => () => num * (
i = -~i % 3,
i === 0 ? a :
i === 1 ? b :
c
))(-1);
}
const itemSelector = 'селектор блока';
const buttonSelector = 'селектор кнопки';$(document).on('click', buttonSelector, function() {
$(this)
.closest(itemSelector)
.prev()
.find(buttonSelector)
.prop('disabled', false);
});
// или
document.addEventListener('click', ({ target: t }) => {
const prev = t
.closest(buttonSelector)
?.closest(itemSelector)
.previousElementSibling
?.querySelector(buttonSelector);
if (prev) {
prev.disabled = false;
}
});
const getFromTree = (tree, childrenKey, getter = n => n) =>
Array.isArray(tree)
? tree.flatMap(n => [
getter(n),
...getFromTree(n[childrenKey], childrenKey, getter),
])
: [];
// или
function* flatTree(tree, childrenKey) {
if (
tree instanceof Object &&
tree[Symbol.iterator] instanceof Function
) {
for (const n of tree) {
yield n;
yield* flatTree(n[childrenKey], childrenKey);
}
}
}const getFromTree = function(tree, childrenKey, getter = n => n) {
const result = [];
for (const stack = this(tree); stack.length;) {
const n = stack.pop();
result.push(getter(n));
stack.push(...this(n[childrenKey]));
}
return result;
}.bind(x => x instanceof Array ? [...x].reverse() : []);
// или
const flatTree = function*(tree, childrenKey) {
const stack = [];
for (let [ i, arr ] = this(tree); ++i < arr.length || stack.length;) {
if (i === arr.length) {
[ i, arr ] = stack.pop();
} else {
yield arr[i];
stack.push([ i, arr ]);
[ i, arr ] = this(arr[i][childrenKey]);
}
}
}.bind(x => [ -1, x?.constructor === Array ? x : [] ]);// т.к. id верхнего уровня получать не желаете, избавимся от него
const withoutTopLevel = data.flatMap(n => n.children);
// если использовать обычную функцию
const ids = getFromTree(withoutTopLevel, 'children', n => n.id);
// или, генератор
const ids = Array.from(flatTree(withoutTopLevel, 'children'), n => n.id);
const createItem = obj => ({ key: `${obj.name}-${obj.id}`, title: obj.name });
const result = Object.values(columnList.reduce((acc, n) => {
(acc[n.table.id] ??= {
...createItem(n.table),
children: [],
}).children.push(createItem(n));
return acc;
}, {}));
const sorted = (arr, key) => arr
.map(n => [ key(n), n ])
.sort(([a], [b]) => a < b ? -1 : +(a > b))
.map(n => n[1]);const sortedArr = sorted(
arr,
n => new Date(n.date.replace(/(\d+)\.(\d+)\.(\d+)/, '$3-$2-$1'))
);
// или
const sortedArr = sorted(
arr,
n => n.date.split('.').reverse().map(m => m.padStart(2, 0)).join('')
);
const getPrimitives = data =>
data instanceof Object
? Object.values(data).flatMap(getPrimitives)
: [ data ];
const result = getPrimitives(obj);function* getPrimitives(data) {
if (data instanceof Object) {
for (const k in data) if (data.hasOwnProperty(k)) {
yield* getPrimitives(data[k]);
}
} else {
yield data;
}
}
const result = [...getPrimitives(obj)];function getNestedData(data, test) {
const result = [];
for (const stack = [ data ]; stack.length;) {
const n = stack.pop();
if (n instanceof Object) {
stack.push(...Object.values(n).reverse());
}
if (test(n)) {
result.push(n);
}
}
return result;
}
const result = getNestedData(obj, x => x !== Object(x));
const data = Array
.from(document.querySelectorAll('.input-container'))
.reduce((acc, el, i) => (
acc[`input${i + 1}`] = [
'parameter',
'result',
'select',
'range',
].map(name => el.querySelector(`[name="${name}"]`).value),
acc
), {});
<div class="colorsSelector">
<div class="colorItem" data-color="blue"></div>
<div class="colorItem" data-color="white"></div>
<div class="colorItem" data-color="red"></div>
<div class="colorItem" data-color="black"></div>
<div class="colorItem" data-color="white-pure"></div>
<div class="colorItem" data-color="orange"></div>
<div class="colorItem" data-color="graphite"></div>
</div>[data-color="blue"] { background-color: #325488; }
[data-color="white"] { background-color: #cfcfcf; }
[data-color="red"] { background-color: #c64040; }
[data-color="black"] { background-color: #08090b; }
[data-color="white-pure"] { background-color: #f0f0f0; }
[data-color="orange"] { background-color: #d87c5a; }
[data-color="graphite"] { background-color: #7f7f7f; }const container = document.querySelector('.colorsSelector');
const itemSelector = '.colorItem';
const activeClass = 'colorItem--active';
const img = document.querySelector('.imgHolder img');
const src = color => `//webcademy.ru/files/js2020/solaris/${color}.png`;
// делегированный обработчик клика назначается контейнеру с цветами
container.addEventListener('click', ({ target: { dataset: { color } } }) => {
if (color) {
img.src = src(color);
document.querySelectorAll(itemSelector).forEach(n => {
n.classList.toggle(activeClass, color === n.dataset.color);
});
}
});
// или, каждому цвету обработчик клика назначается индивидуально
const items = container.querySelectorAll(itemSelector);
items.forEach(n => n.addEventListener('click', onClick));
function onClick({ target: t }) {
img.src = src(t.dataset.color);
items.forEach(n => n.classList.toggle(activeClass, n === t));
}
const result = arr.reduce((acc, n) => acc * n.values, 1);const result = eval(arr.map(n => n.values).join('*')) ?? 1;let result = 1;
for (const { values: n } of arr) {
result *= n;
}let result = 1;
for (let i = 0; i < arr.length; i++) {
result = result * arr[i].values;
}const result = (function mul(i) {
return i >= arr.length
? 1
: arr[i].values * mul(-~i);
})(0);
const url = new URL('https://qna.habr.com/?test=123&frukt=yabloko');
console.log(url.searchParams.get('test'));const str = 'https://qna.habr.com/?test=123&frukt=yabloko';
const usp = new URLSearchParams(str.replace(/^[^?]*\?/, '')); // или str.split('?').pop()
console.log(usp.get('test'));
[ 5, 8, 10 ].forEach((n, i, a) => $items.slice(a[i - 1], n).wrapAll('<div>'));
const elements = document.querySelectorAll('.wrapper-boxes');
const tag = 'button';
const text = 'click me';
const className = 'xxx';elements.forEach(n => {
n.after(document.createElement(tag));
n.nextSibling.textContent = text;
n.nextSibling.classList.add(className);
});for (const { parentNode, nextSibling } of elements) {
const el = document.createElement(tag);
el.innerText = text;
el.className = className;
parentNode.insertBefore(el, nextSibling);
}for (let i = 0; i < elements.length; i++) {
elements[i].insertAdjacentHTML(
'afterend',
`<${tag} class="${className}">${text}</${tag}>`
);
}(function insert(i, n = elements.item(i)) {
if (n) {
const el = document.createElement(tag);
el.appendChild(new Text(text));
el.classList.value = className;
n.insertAdjacentElement('afterend', el);
insert(-~i);
}
})(0);
const arr = Object
.entries(obj)
.reduce((acc, [ k, values ]) => (
values.forEach((v, i) => (acc[i] ??= {})[k] = v),
acc
), []);const keys = Object.keys(obj);
const arr = obj[keys[0]]?.map((_, i) => {
return Object.fromEntries(keys.map(k => [ k, obj[k][i] ]));
}) ?? [];const zip = (arrs, defaultValue = null) =>
Array.from(
{ length: Math.max(...arrs.map(n => n.length)) },
(_, i) => arrs.map(n => i < n.length ? n[i] : defaultValue)
);
const combine = (keys, values, defaultValue = null) =>
keys.reduce((acc, n, i) => (
acc[n] = i < values.length ? values[i] : defaultValue,
acc
), {});
const arr = Array.from(
zip(Object.values(obj)),
combine.bind(null, Object.keys(obj))
);
const index = 0;.const duplicates = arr.filter((n, i, a) => a.filter(m => m[index] === n[index]).length > 1);const duplicates = Object
.values(arr.reduce((acc, n) => ((acc[n[index]] ??= []).push(n), acc), {}))
.flatMap(n => ~-n.length ? n : []);const duplicates = Array
.from(arr.reduce(
(acc, n) => (acc.get(n[index]).push(n), acc),
new Map(arr.map(n => [ n[index], [] ]))
).values())
.reduce((acc, n) => (n.length > 1 && acc.push(...n), acc), []);const duplicates = arr.filter(function(n) {
return this.get(n[index]);
}, arr.reduce((acc, { [index]: n }) => acc.set(n, acc.has(n)), new Map));
document.querySelector('.btn--start').addEventListener('click', filterItems);
document.querySelector('select').addEventListener('change', e => e.target.value === 'all' && filterItems());
function filterItems() {
const val = document.querySelector('select').value;
document.querySelectorAll('.item').forEach(n => {
n.style.display = [ n.dataset.elem, 'all' ].includes(val)
? 'block'
: 'none';
});
}