Сделал вот так: str.split("/").slice(-2, -1).join(""), но думаю, что есть решение попроще./[^\/]+(?=\/$)/.exec(str)[0]
// или
str.match(/[^\/]+/g).pop()
// или
str.split('/').at(-2)
Хук get не позволяет получить параметры вызова метода
function sequence(functions) {
return new Proxy(functions, {
get(target, key) {
const val = target[key];
return val instanceof Function
? (...args) => {
console.log(`method "${key}" called with arguments: `, args);
return val.apply(target, args);
}
: val;
},
});
}
const uniqueWithSum = arr =>
arr.reduce((acc, n) => {
const keys = n.slice(0, -1);
const item = acc.find(m => m.length === n.length && keys.every((k, i) => k === m[i]));
(item ?? (acc[acc.length] = [ ...keys, 0 ]))[keys.length] += n[keys.length];
return acc;
}, []);const uniqueWithSum = (function(arr) {
const indexTree = new Map;
return arr.reduce((acc, [...keys]) => {
const val = keys.pop();
const indexes = keys.reduce((p, c) => p.set(c, p.get(c) ?? new Map).get(c), indexTree);
const index = indexes.set(this, indexes.get(this) ?? ~-acc.push([ ...keys, 0 ])).get(this);
acc[index][keys.length] += val;
return acc;
}, []);
}).bind(Symbol());const uniqueWithSum = arr =>
[...arr.reduce((acc, n) => {
const end = n.length - 1;
const key = n.reduce((p, c, i) => i === end ? p : p.set(c, p.get(c) ?? new Map).get(c), acc[0]);
acc[1].set(key, acc[1].get(key) ?? n.map((m, i) => i !== end && m)).get(key)[end] += n[end];
return acc;
}, [ new Map, new Map ])[1].values()];
const replaceKeys = (value, replacer) =>
value instanceof Object
? value instanceof Array
? value.map(n => replaceKeys(n, replacer))
: Object.fromEntries(Object
.entries(value)
.map(n => [ replacer(n[0]), replaceKeys(n[1], replacer) ])
)
: value;function replaceKeys(value, replacer) {
const stack = [];
const clones = new Map;
const getClone = v => v instanceof Object
? (clones.has(v) || stack.push([ v, clones.set(v, v.constructor()).get(v) ]),
clones.get(v))
: v;
for (getClone(value); stack.length;) {
const [ source, target ] = stack.pop();
const isArray = Array.isArray(source);
for (const k in source) if (Object.hasOwn(source, k)) {
target[isArray ? k : replacer(k)] = getClone(source[k]);
}
}
return getClone(value);
}const newObj = replaceKeys(obj, key => `${key}_upd`);
const regex = /#[a-f\d]+;$/i;
const replacement = '<span class="color" style="background: $&"></span>';
document.querySelectorAll('селектор сами сообразите').forEach(n => {
n.innerHTML = n.innerText.replace(regex, replacement);
});
const result = arr.reduce((acc, n, i, a) => (
n === a[i - 1] + 1 || acc.push([]),
acc.at(-1).push(n),
acc
), []);function* groupAdjacent(
data,
{
key = n => n,
newGroup = (c, p) => c !== p,
} = {}
) {
const iter = data[Symbol.iterator]();
const getVal = key instanceof Function ? key : n => n[key];
for (
let group = [], prev = null, n, i = -1;
!n?.done && (n = iter.next());
n.done || group.push(n.value)
) {
let groupDone = false;
if (!n.done) {
const curr = getVal(n.value, ++i);
groupDone = i && newGroup(curr, prev);
prev = curr;
}
if ((n.done && group.length) || groupDone) {
yield group;
group = [];
}
}
}const result = [...groupAdjacent(arr, { newGroup: (c, p) => c !== -~p })];
// или
const result = Array.from(groupAdjacent(arr, { key: (n, i) => n - i }));
.product. Вместо первого .product нужен тот, внутри которого находится нажатая кнопка:document.querySelector('.wrapper_product') ---> event.target
menu.addEventListener('click', ({ target: t }) => {
if (t.tagName === 'SPAN') {
const parent = t.parentNode;
parent.classList.toggle('active');
for (const n of menu.querySelectorAll('.active')) {
if (n !== parent) {
n.classList.toggle('active', n.contains(parent));
}
}
}
});- .menu_list_item.active .submenu {
+ .active > .submenu {- .submenu_list_item.active .product {
+ .active > .product {const container = document.querySelector('#menu');
const itemSelector = 'li';
const buttonSelector = `${itemSelector} span`;
const activeClass = 'active';
container.addEventListener('click', function({ target: t }) {
if (t = t.closest(buttonSelector)?.closest(itemSelector)) {
t.classList.toggle(activeClass);
this.querySelectorAll(`.${activeClass}`).forEach(n => {
if (n !== t) {
n.classList.toggle(activeClass, n.contains(t));
}
});
}
});
const items = document.querySelectorAll('.faq__input');
const onChange = ({ target: t }) => t
.closest('.faq__items')
.querySelectorAll('.faq__question--top')
.forEach(n => n.classList.toggle('active', n.nextElementSibling.checked));
items.forEach(n => n.addEventListener('change', onChange));.faq__item вместо .faq__question--top. Если в будущем задумаете стилизовать внутри выбранного .faq__item элементы, находящиеся за пределами .faq__question--top, то не придётся переписывать js-код.const itemSelector = '.faq__item';
const radioSelector = '.faq__input';
const activeClass = 'active';
const toggleActiveClass = radioGroupName => document
.querySelectorAll(`${radioSelector}[name="${radioGroupName}"]`)
.forEach(n => n.closest(itemSelector).classList.toggle(activeClass, n.checked));document.querySelectorAll(radioSelector).forEach(function(n) {
n.addEventListener('change', this);
}, e => toggleActiveClass(e.target.name));document.addEventListener('change', ({ target: t }) => {
if (t.matches(radioSelector)) {
toggleActiveClass(t.name);
}
});
value из первого массива аналогичное значение code во втором)? Если это не важно и вас устраивает возможное получение undefined, тогдаconst result = array1.map(n => array2.find(m => m.code === n.value));const obj2 = Object.fromEntries(array2.map(n => [ n.code, n ]));
const result = array1.reduce((acc, n) => (
(n = obj2[n.value]) && acc.push(n),
acc
), []);const result = array1.map(function({ value: n }) {
return this.get(n) ?? `объект с code="${n}" отсутствует`;
}, new Map(array2.map(n => [ n.code, n ])));code во втором массиве быть неуникальны? Если да, и надо получать все объекты с указанными code, а не один, то можно предварительно сгруппировать второй массив по значениям code:const result = array1.flatMap(function(n) {
return this[n.value] ?? [];
}, array2.reduce((acc, n) => ((acc[n.code] ??= []).push(n), acc), {}));array2, то его и надо перебирать при извлечении объектов, а не первый массив:const result = array2.filter(function(n) {
return this.has(n.code);
}, new Set(array1.map(n => n.value)));
e.target.dataset.followerStylee.target? Ну, когда вы наводите курсор на слайд с data-атрибутом. На тот слайд, который не видно за вложенной в него картинкой.target хватать, а пытаться найти у него предка с нужным вам атрибутом.
const result = Object.values(arr.reduce((max, n) => (
max[n.group] = +max[n.group]?.score > +n.score ? max[n.group] : n,
max
), {}));function group(data, key, val = n => n) {
const getKey = key instanceof Function ? key : n => n[key];
const getVal = val instanceof Function ? val : n => n[val];
const result = new Map;
for (const n of data) {
const k = getKey(n);
result.set(k, result.get(k) ?? []).get(k).push(getVal(n));
}
return result;
}
function max(data, key = n => n) {
const getVal = key instanceof Function ? key : n => n[key];
let result = null;
for (const n of data) {
const val = getVal(n);
result = result?.[1] >= val ? result : [ n, val ];
}
return result?.[0];
}const result = Array.from(
group(arr, 'group').values(),
n => max(n, m => +m.score)
);
// значения withSeat вместо раскладывания в отдельные переменные собираете в объект
const withSeat = {
adult: 1,
teenager: 1,
babe: 0,
};
const passengers = cabins.flatMap(n => Object
.entries(n)
.flatMap(([ k, v ]) => Array.from(
{ length: v },
() => ({ withSeat: withSeat[k] })
))
);
const obj = Object.fromEntries(Object
.entries(arr
.flatMap(Object.entries)
.reduce((acc, n) => ((acc[n[0]] ??= new Set).add(n[1]), acc), {}))
.map(([ k, v ]) => [ k, v.size === 1 ? [...v][0] : null ])
);const obj = arr.reduce((acc, n) => (
Object.keys(n).forEach(k => {
acc[k] = Object.hasOwn(acc, k) && n[k] !== acc[k] ? null : n[k];
}),
acc
), {});
formatDate(date) {
const today = new Date();
return [ 'getFullYear', 'getMonth', 'getDate' ].every(n => date[n]() === today[n]())
? 'Today'
: flatpickr.formatDate(date, 'j M');
},
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);
}
});