const getNestedItems = (data, test) =>
data instanceof Object
? Object.values(data).flatMap(n => getNestedItems(n, test))
: test(data) ? [ data ] : [];
const result = getNestedItems(obj, x => /^[A-Z]+$/.test(x)).join('');function* getNestedItems(data, test) {
if (Object(data) === data) {
for (const k in data) if (Object.hasOwn(data, k)) {
yield* getNestedItems(data[k], test);
}
} else if (test(data)) {
yield data;
}
}
const result = ''.concat(...getNestedItems(obj, x => x?.toUpperCase?.() === x));
все с атрибутом required
const className = 'здесь ваш класс';const inputs = document.querySelectorAll(`.${className}`);
// или
const inputs = document.getElementsByClassName(className);const isFilled = [...inputs].every(n => n.value);
// или
const isFilled = !Array.prototype.some.call(inputs, n => !n.value);
// или
let isFilled = true;
for (const n of inputs) {
if (!n.value) {
isFilled = false;
break;
}
}
// или
let isFilled = true;
for (let i = -1; ++i < inputs.length && (isFilled = !!inputs[i].value);) ;
// или
const isFilled = !(function isEmpty(i, n = inputs.item(i)) {
return n && (!n.value || isEmpty(-~i));
})(0);
if (this.frame < 0) { this.frame = this.slides.lenght-1; this.setBackground(this.slides[this.frame]) }
frame неотрицательный, то вызывать setBackground уже не надо?undefined. А после вычитания единицы - NaN. Элемента с индексом NaN в массиве нет, так что в setBackground улетает undefined - его вы и видите в стилях.if (this.frame > this.slides.length) {buttonLeft.addEventListener('click', slider.left());
while не совсем удобен
while заменить на for, переместить вызов exec в условие продолжения цикла - получится одна строка вместо трёх, область видимости вне цикла не загажена не нужной там переменной, вроде бы неплохо:for (let m; m = re.exec(str);) {
console.log(m.groups);
}exec стоит по другой причине. Проблема в том, что если забыть флаг g при определении регулярного выражения, то exec будет при каждом вызове выдавать первое совпадение, т.е., цикл получится бесконечным. А вот с matchAll такой ерунды не случится, без флага выдаст ошибку:for (const { groups } of str.matchAll(re)) {
console.log(groups);
}
Array.from(
arr.reduce((acc, n) => acc.set(n, -~acc.get(n)), new Map),
n => [ n[0], (n[1] / arr.length * 100).toFixed(2) + '%' ]
)
const clone = (data, replacements) =>
data instanceof Object
? data instanceof Array
? data.map(n => clone(replacements?.hasOwnProperty(n) ? replacements[n] : n, replacements))
: Object.fromEntries(Object.entries(data).map(([ k, v ]) => [
k,
clone(replacements?.hasOwnProperty(k) ? replacements[k] : v, replacements)
]))
: data;const products = arr.map(n => clone(obj.product[0], n));
"[object Object]". Всё.toString (конечно, поступать так имеет смысл только в том случае, если вы можете гарантировать, что строковые представления будут уникальны).
out.textContent = badWords.reduce(
(str, n) => str.replaceAll(n, '*'.repeat(n.length)),
field
);for (const n of badWords) {
field = field.replace(RegExp(n, 'g'), Array(n.length + 1).join('*'));
}
out.innerText = field;out.innerHTML = (function replace(str, i, n = badWords[i]) {
return n
? replace(str.split(n).join(Array(n.length).fill`*`.join``), -~i)
: str;
})(field, 0);out.replaceChildren(field.replace(
RegExp(badWords.join('|'), 'g'),
m => m.replaceAll(/./g, '*')
));
let index = -1;
setInterval(el => {
const show = !el.classList.contains('_active');
index = (index + show) % infoModal.length;
el.innerText = infoModal[index].title;
el.classList.toggle('_active', show);
}, 1000, document.querySelector('.modal__title'));Если, к примеру, нужно скрывать блок каждый раз через5 сек, а показывать блок через рандомный промежуток времени?
(function updateText(el, i) {
const show = el.classList.toggle('_active');
i = (i + show) % infoModal.length;
el.textContent = infoModal[i].title;
setTimeout(updateText, 1000 + !show * Math.random() * 3000, el, i);
})(document.querySelector('.modal__title'), -1);
document.querySelector('form').addEventListener('input', e => {
document.querySelector('button').disabled = ![
[ 'input', el => el.value ],
[ 'select', el => el.selectedIndex ],
].every(([ selector, validator ]) => {
return [...e.currentTarget.querySelectorAll(selector)].every(validator);
});
});
const entries = Object.entries(obj); for (const entry of entries) { if (!isObject(entry)) { result = Object.assign(result, Object.fromEntries(entry)); } else return cloneDeep(entry);
const arrs = [ arr1, arr2 ];.const result = arrs.reduce((acc, n) => (
n.forEach((m, i) => Object.assign(acc[i] ??= {}, m)),
acc
), []);function* zip(data, defaultValue = null) {
const iterators = Array.from(data, n => n[Symbol.iterator]());
for (let doneAll = false; doneAll = !doneAll;) {
const values = [];
for (const n of iterators) {
const { value, done } = n.next();
values.push(done ? defaultValue : value);
doneAll &&= done;
}
if (!doneAll) {
yield values;
}
}
}
const result = Array.from(zip(arrs), n => Object.assign({}, ...n));
function replaceText(node, replacer) {
if (node.nodeType === Node.ELEMENT_NODE) {
node.childNodes.forEach(n => replaceText(n, replacer));
} else if (node.nodeType === Node.TEXT_NODE) {
node.textContent = replacer(node.textContent);
}
}function replaceText(node, replacer) {
const iter = document.createNodeIterator(node, NodeFilter.SHOW_TEXT);
for (let n = null; n = iter.nextNode();) {
n.nodeValue = replacer(n.nodeValue);
}
}replaceText(document.body, str => str.replace(/\d/g, 'hello, world!!'));
document.querySelector('.ticket_content').addEventListener('input', e => {
document.querySelector('.ticket_price').innerText =
Array.prototype.reduce.call(
e.currentTarget.querySelectorAll('.plus_minus'),
(acc, n) => acc + n.querySelector('input').value * n.nextElementSibling.innerText,
0
);
});
const containers = document.querySelectorAll('.item');
const setTexts = (container, index) => container
.querySelectorAll('.card-item')
.forEach(n => n.textContent = `button ${-~index}`);// индекс передаётся в коллбек forEach'а
containers.forEach(setTexts);
// или, индекс отдаёт итератор entries
for (const [ i, n ] of containers.entries()) {
setTexts(n, i);
}
// или, можно самостоятельно обновлять значение переменной с индексом
for (let i = 0; i < containers.length; i++) {
setTexts(containers[i], i);
}
// и цикл для этого использовать не обязательно
(function next(i, n = containers.item(i)) {
n && (setTexts(n, i), next(i + 1));
})(0);
const bullshitInsert = str => str
.replace(/(?<=[2468])(?=[2468])/g, '*')
.replace(/(?<=[13579])(?=[13579])/g, '-');const bullshitInsert = str => Array
.from(str, (n, i) => (n * str[i - 1] && !((n ^ str[i - 1]) & 1) ? '*-'[n & 1] : '') + n)
.join('');
const result = Object
.entries(arr.reduce((acc, n) => ((acc[n.name] ??= []).push(n.value), acc), {}))
.reduce((acc, [ k, v ]) => (acc[k] = v.length === 1 || v, acc), {});ThirdName: truetrue там, где значение одно:const result = Object
.entries(arr.reduce((acc, n) => ((acc[n.name] ??= new Set).add(n.value), acc), {}))
.reduce((acc, [ k, [...v] ]) => (acc[k] = ~-v.length ? v : v[0], acc), {});
const filter = (arr, conditions) =>
arr.filter(
function(n) {
return this.every(([ k, values ]) => values.some(v => v.includes(n[k])));
},
Object
.entries(conditions)
.map(n => [ n[0], [].concat(n[1]).map(String) ])
.filter(n => n[1].length)
);
А лучше всего просто объяснить что бы я в итоге допер сам!
const defaultValue = null;.Предполагаю что надо использовать reduce.
const result = arr1.reduce((acc, n) => (
acc.push(arr2.find(m => m.uniq === +n)?.sum ?? defaultValue),
acc
), []);const result = [];
for (const n of arr1) {
let item = defaultValue;
for (const m of arr2) {
if (m.uniq == n) {
item = m.sum;
break;
}
}
result[result.length] = item;
}const sums = Object.fromEntries(arr2.map(n => [ n.uniq, n.sum ]));
const result = (function get(i, n = arr1[i]) {
return i < arr1.length
? [ Object.hasOwn(sums, n) ? sums[n] : defaultValue, ...get(-~i) ]
: [];
})(0);map. Это ведь совсем не круто - идти наиболее простым и очевидным путём:const result = arr1.map(function(n) {
return this.has(n) ? this.get(n) : defaultValue;
}, new Map(arr2.map(n => [ `${n.uniq}`, n.sum ])));