const groupSelector = 'fieldset.js-tree-box';
const mainSelector = 'legend input';
const itemSelector = 'legend + span input';
const activeClass = 'active';
document.addEventListener('change', ({ target: t }) => {
const group = t.closest(groupSelector);
if (group) {
const main = group.querySelector(mainSelector);
const items = [...group.querySelectorAll(itemSelector)];
if (main === t) {
items.forEach(n => n.checked = t.checked);
} else {
const numChecked = items.reduce((acc, n) => acc + n.checked, 0);
main.checked = numChecked === items.length;
main.indeterminate = 0 < numChecked && numChecked < items.length;
}
group.classList.toggle(activeClass, main.checked);
}
});
const sorted = (data, key) => Array
.from(data, n => [ n, key(n) ])
.sort((a, b) => a[1] - b[1])
.map(n => n[0]);document.querySelector('.result').append(...sorted(
document.querySelector('.data').cloneNode(true).children,
n => +n.innerText
));
делегирование не работает
в консоли выдает "e.target.closest is not a function"
const hoverCellNum = hoverCell.getAttribute('data-tdnum');
document.addEventListener('mouseenter', ({ target: t }) => {
if (t.matches?.('td._hight-light__cell')) {
t.closest('tbody').querySelectorAll('.table-big__row').forEach(n => {
n.cells[t.cellIndex].classList.add('_hover');
});
}
}, true);
document.addEventListener('mouseleave', e => {
if (e.target.matches?.('td._hight-light__cell')) {
document.querySelectorAll('._hover').forEach(n => n.classList.remove('_hover'));
}
}, true);
document.addEventListener('click', updateCounter);
document.addEventListener('input', updateCounter);
document.querySelectorAll('.tariff__counter').forEach(n => {
const max = n.dataset.seats;
n.querySelectorAll('.tariff__counter-max').forEach(m => m.innerText = max);
n.querySelectorAll('.amount').forEach(m => m.max = max);
n.querySelectorAll('button').forEach(m => m.dataset.change = m.innerText === '+' ? 1 : -1);
});
function updateCounter({ target: t }) {
const input = t.closest('.tariff__counter-block')?.querySelector('.amount');
if (input) {
const { min, max, value } = input;
input.value = Math.max(min, Math.min(max, (value | 0) + (t.dataset.change | 0)));
}
}
const keys = [ 'id', 'secondId' ];
const result = firstArray.map(n => secondArray.find(m => keys.every(k => n[k] === m[k])) ?? n);const arrToTree = (arr, keys) =>
arr.reduce((acc, n) => (
keys.reduce((p, c, i) => p[n[c]] ??= i + 1 === keys.length ? n : {}, acc),
acc
), {});
const keys = [ 'id', 'secondId' ];
const tree = arrToTree(secondArray, keys);
const result = firstArray.map(n => keys.reduce((p, c) => p?.[n[c]], tree) ?? n);const arrToTree = (arr, keys) =>
arr.reduce((acc, n) => (
keys(n).reduce(
(p, c, i, a) => p.set(c, p.get(c) ?? (-~i === a.length ? n : new Map)).get(c),
acc
),
acc
), new Map);
const keys = n => [ n.id, n.secondId ];
const result = firstArray.map(function(n) {
return keys(n).reduce((p, c) => p?.get(c), this) ?? n;
}, arrToTree(secondArray, keys));
function getLeaves(tree) {
const result = [];
for (const stack = [...tree]; stack.length;) {
const n = stack.pop();
if (Array.isArray(n.children) && n.children.length) {
stack.push(...n.children);
} else {
result.push(n);
}
}
return result.reverse();
}
const leaves = getLeaves(tree);const getFromTree = function*(tree, test) {
const stack = [];
for (let [ i, arr ] = this(tree); ++i < arr.length || stack.length;) {
if (i === arr.length) {
[ i, arr ] = stack.pop();
} else {
if (test(arr[i])) {
yield arr[i];
}
stack.push([ i, arr ]);
[ i, arr ] = this(arr[i].children);
}
}
}.bind(x => [ -1, x instanceof Array ? x : [] ]);
const leaves = [...getFromTree(tree, n => !n.children?.length)];
function groupSum(arr, key, ...sumKeys) {
const getKey = key instanceof Function ? key : n => n[key];
return Object.values(arr.reduce((acc, n) => {
const item = acc[getKey(n)] ??= Object.assign(
structuredClone(n),
Object.fromEntries(sumKeys.map(k => [ k, 0 ]))
);
sumKeys.forEach(k => item[k] += n[k]);
return acc;
}, {}));
}// ваш случай
groupSum(arr, 'product', 'price', 'selling_price', 'quantity')
// элементам исходного массива не обязательно быть объектами,
// это могут быть и массивы
groupSum([
[ 'A', 1, 10 ],
[ 'A', 2, 20 ],
[ 'A', 3, 30 ],
[ 'B', 1, 5 ],
[ 'B', 10, 5 ],
[ 'B', 100, 5 ],
], 0, 1, 2) // [ [ 'A', 6, 60 ], [ 'B', 111, 15 ] ]
[
[ '.btn-all', 'click', onGetDataClick ],
[ '.elem button', 'click', onPlusMinusClick ],
[ '.amount', 'input', onAmountInput ],
].forEach(([ selector, type, handler ]) => {
document.querySelectorAll(selector).forEach(n => n.addEventListener(type, handler));
});
function onGetDataClick(e) {
const data = Array.prototype.flatMap.call(
e.target.closest('.child-block').querySelectorAll('.elem'),
n => Array(+n.querySelector('.amount').value).fill(+n.dataset.id)
);
console.log(data);
}
function onPlusMinusClick({ target }) {
const input = target.closest('.elem').querySelector('.amount');
input.value -= target.innerText === '+' ? -1 : 1;
input.dispatchEvent(new Event('input'));
}
function onAmountInput({ target: t }) {
t.value = Math.max(t.min, Math.min(t.max, t.value | 0));
}
const obj = {
a: {
b: {
c: {
xxx: 666,
},
},
},
};
const proxy = new Proxy(obj, {
get(target, key) {
return key.split('.').reduce((p, c) => p?.[c], target);
},
set(target, key, val) {
const keys = key.split('.');
const k = keys.pop();
keys.reduce((p, c) => p[c] ??= {}, target)[k] = val;
return true;
},
});
console.log(proxy['a.b.c.xxx']); // 666
proxy['x.y.z'] = 187;
console.log(obj.x.y.z); // 187
// имена свойств можно передавать в виде массива
const pick = (obj, keys) => Object.fromEntries(keys.map(n => [ n, obj[n] ]));
const newObj = pick(obj, [ 'b', 'c' ]);
// или как отдельные значения
const pick = (obj, ...keys) => keys.reduce((acc, n) => (acc[n] = obj[n], acc), {});
const newObj = pick(obj, 'b', 'c');const pickExisting = (obj, keys) =>
Object.fromEntries(keys.filter(n => n in obj).map(n => [ n, obj[n] ]));const pickOwn = (obj, keys) =>
keys.reduce((acc, n) => (Object.hasOwn(obj, n) && (acc[n] = obj[n]), acc), {});const pick = (obj, filterFn) => Object.fromEntries(Object.entries(obj).filter(filterFn));
const obj1 = pick(obj, ([ k, v ]) => 'abc'.includes(k) && v % 2); // {a: 1, c: 3}
const obj2 = pick(obj, n => n[1] > 2); // {c: 3, d: 5}
const nested = {
_keys: arr => arr
.flat(Infinity)
.flatMap(n => typeof n === 'string' ? n.split('.') : n),
get(obj, ...args) {
return nested._keys(args).reduce((p, c) => p?.[c], obj);
},
set(obj, ...args) {
const val = args.pop();
const keys = nested._keys(args);
const key = keys.pop();
return keys.reduce((p, c) => p[c] ??= {}, obj)[key] = val;
},
};nested.set(this.data, args, value);.nested.get([], 'constructor.prototype', [ 'at', [[[ 'name' ]]] ], 'length') // 2
nextSlide() { ---> nextSlide = () => {.onclick = this.nextSlide; ---> .onclick = () => this.nextSlide();.onclick = this.nextSlide; ---> .onclick = this.nextSlide.bind(this);this.
str.split(/(?<=\S)\s*(?=[А-ЯЁ])/).join(' ')
// или
str.replace(/(?<=\S)(?=[А-ЯЁ])/g, ' ')
// или
str.replace(/(\S)(?=[А-ЯЁ])/g, '$1 ')
// или
str.replace(/[А-ЯЁ]/g, (m, i) => i && str[~-i] !== ' ' ? ' ' + m : m)
.filter(function (el, i) { return arr[i] === el[i]; })
0? Или 5? А зачем тогда [i]? Может, должно было быть arr[i] === el?const arr = Array.from({ length: hMax }, (_, i) => i + 1);
const result = arr.reduce((acc, number) => (
Array.prototype.reduce.call(
`${number}`,
(diff, digit) => diff - digit ** exp,
number
) || acc.push(number),
acc
), []);const result = [];
for (let i = 1; i <= hMax; i++) {
let sum = 0;
for (let j = i; j; j = Math.floor(j / 10)) {
sum += (j % 10) ** exp;
}
if (i === sum) {
result[result.length] = i;
}
}
const searchOptions = [
[ '#search_table', tr => $('input[name^=name]', tr).val() ],
[ '#search_card', tr => $('[data-item-name="name"]', tr).text() ]
];
$(searchOptions.map(n => n[0]).join(', ')).on('input', () => {
const values = searchOptions.map(n => $(n[0]).val().toLowerCase());
$('#tabname tbody tr')
.hide()
.filter((i, n) => searchOptions.every((m, j) => m[1](n).toLowerCase().includes(values[j])))
.show();
});
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.replace(/(\d+)\.(\d+)\.(\d+),/, '$3-$2-$1'))
);
// или
const sortedArr = sorted(
arr,
n => n.replace(/[^,]+/, m => m.split('.').reverse().join(''))
);
const replacement = '!!!';.const newStr = str.replace(/(?<=\/)[^\/]*(?=\/[^\/]*$)/, replacement);
// или
const newStr = str
.split('/')
.map((n, i, a) => i && i === a.length - 2 ? replacement : n)
.join('/');
// или
const i = str.lastIndexOf('/');
const j = i > 0 ? -~str.lastIndexOf('/', ~-i) : 0;
const newStr = j ? str.slice(0, j) + replacement + str.slice(i) : str;
`${arr}`.match(/\b\w{5}\b/g) || []
// или
arr.reduce((acc, n) => (n.length ^ '0b101' || acc.push(n), acc), [])
// или
arr.filter(n => n[4] && !n[-~4])
// или
arr.filter(RegExp.prototype.test.bind(/^.....$/))
// или
arr.reduce((acc, n) => ((acc[n.search('$')] ??= []).push(n), acc), {})[5] ?? []
// или
(function get(i, n = arr[--i]) {
return i >= 0
? get(i).concat(5 - [].push(...n) ? [] : n)
: [];
})(arr.length)