filter
(а ещё Safari - говорят, яблочные уроды пока не реализовали поддержку методов итераторов; впрочем, сделать обычный for...of
вместо reduce
не проблема):function countIntersections(data1, data2, key = n => n) {
const getKey = key instanceof Function ? key : n => n[key];
const keys = new Set(Array.from(data2, getKey));
return data1[Symbol.iterator]().reduce((acc, n) => acc + keys.has(getKey(n)), 0);
}
const result = countIntersections(newWord, glas);
.countIntersections(Array(7).keys(), Array(4).keys()) // 4
countIntersections('abCdE', 'ACe', n => n.toLowerCase()) // 3
countIntersections([ { id: 1 }, { id: 2 }, { id: 3 } ], [ { id: 3 } ], 'id') // 1
- app.component('draggable', window['vue3-draggable']);
+ app.component('draggable', window['vue3-draggable'].default);
$result = [];
foreach ($arr as $n) {
for ($visited = []; array_key_exists($n, $arr); $visited[] = $n, $n = $arr[$n]) {
if (($i = array_search($n, $visited)) !== false) {
$loop = array_slice($visited, $i);
if (empty(array_intersect(array_column($result, 0), $loop))) {
$result[] = $loop;
}
break;
}
}
}
$result = [];
$visited = [];
$iLoop = -1;
foreach ($arr as $n) {
for ($iLoop++; isset($arr[$n]); $visited[$n] = $iLoop, $n = $arr[$n]) {
if (isset($visited[$n])) {
if ($visited[$n] === $iLoop) {
for ($loop = [ $m = $n ]; ($m = $arr[$m]) !== $n; $loop[] = $m) ;
$result[] = $loop;
}
break;
}
}
}
$grouped = [];
foreach ($arr as [ 'id' => $id, 'name' => $name, 'key' => $key ]) {
$grouped[$key][$name] ??= [ 'name' => $name, 'ids' => [] ];
$grouped[$key][$name]['ids'][] = $id;
}
foreach ($keys as $k) {
$$k = array_map(fn($n) => [
'name' => $n['name'],
'ids' => implode(', ', $n['ids'])
], array_values($grouped[$k] ?? []));
}
// такого у вас сейчас нет, сами догадайтесь, кому надо класс добавить
const containerSelector = '.container';
const buttonsSelector = `${containerSelector} .filter__navigation`;
const buttonSelector = `${buttonsSelector} [data-filter]`;
const buttonActiveClass = '_active';
const itemsSelector = `${containerSelector} .search__body`;
const itemSelector = `${itemsSelector} .filter-column`;
const itemHiddenClass = '_hide';
const itemFilterClassPrefix = 'filter__column_';
document.querySelectorAll(buttonSelector).forEach(n => {
n.addEventListener('click', onFilterButtonClick);
});
function onFilterButtonClick({ currentTarget: { dataset: { filter } } }) {
const activeItemClass = itemFilterClassPrefix + filter;
this.closest(buttonsSelector).querySelectorAll(buttonSelector).forEach(n => {
n.classList.toggle(buttonActiveClass, n === this);
});
this.closest(containerSelector).querySelectorAll(itemSelector).forEach(({ classList: cl }) => {
cl.toggle(itemHiddenClass, filter !== 'all' && !cl.contains(activeItemClass));
})
}
document.addEventListener('click', e => {
const button = e.target.closest(buttonSelector);
if (button) {
const { filter } = button.dataset;
const activeItemSelector = filter === 'all' ? '*' : `.${itemFilterClassPrefix}${filter}`;
for (const n of button.closest(buttonsSelector).children) {
n.classList.toggle(buttonActiveClass, n === button);
}
for (const n of button.closest(containerSelector).querySelector(itemsSelector).children) {
n.classList.toggle(itemHiddenClass, !n.matches(activeItemSelector));
}
}
});
{ 'старый ключ': 'новый ключ' }
:const keys = {
x: 'a',
y: 'b',
z: 'c',
};
const renameKeys = (obj, keys) =>
Object.fromEntries(Object
.entries(obj)
.map(([ k, v ]) => [ Object.hasOwn(keys, k) ? keys[k] : k, v ])
);
// или
const renameKeys = (obj, keys) =>
Object.keys(obj).reduce((acc, k) => (
acc[keys[k] ?? k] = obj[k],
acc
), {});
const newArr = arr.map(n => renameKeys(n, keys));
function renameKeys(keys, obj) {
for (const k in keys) {
if (obj.hasOwnProperty(k)) {
obj[keys[k]] = obj[k];
delete obj[k];
}
}
}
arr.forEach(renameKeys.bind(null, keys));
элемент.insertAdjacentHTML('afterend', разметка);
элемент.remove();
// или
элемент.outerHTML = разметка;
<el-table
ref="table"
...
>
...
const table = ref();
onMounted(() => {
new Sortable(table.value.$el.querySelector('thead tr'), {
handle: 'span',
onEnd(e) {
columns.value.splice(e.newIndex, 0, columns.value.splice(e.oldIndex, 1)[0]);
},
});
});
colors: markerColors, // Устанавливаем цвета маркеров в зависимости от результата
discrete
, позволяющим индивидуально настраивать внешний вид каждого маркера. Всплывающую подсказку это никак не затрагивает, так что её придётся кастомизировать отдельно. function bindRootContext(obj, context = obj) {
return new Proxy(obj, {
get(target, key) {
const val = target[key];
return (
val instanceof Function ? val.bind(Object.hasOwn(target, key) ? context : target) :
val instanceof Object ? bindRootContext(val, context) :
val
);
},
});
}
const obj = bindRootContext({
name: 'Root',
a: {
name: 'A',
logName() { console.log(this.name); },
b: {
name: 'B',
logName() { console.log(this.name); },
arr: [
{
name: '666',
logName() { console.log(this.name); },
},
function() { console.log(this.name); },
],
c: {
name: 'C',
logName() { console.log(this.name); },
},
},
},
});
obj.a.b.c.logName(); // Root
obj.a.b.logName(); // Root
obj.a.logName(); // Root
obj.a.b.arr[0].logName(); // Root
obj.a.b.arr[1](); // Root
Можно ли пользоваться структурами данных из SDK при решении алгоритмических секций?
читинг или норм решение?
mergedList.sort()
кнопка.addEventListener('click', () => {
const [ li ] = шаблон.content.cloneNode(true).children;
li.querySelector('.card__image').src = инпут_с_ссылкой.value;
li.querySelector('.card__title').textContent = инпут_с_подписью.value;
список.insertAdjacentElement('afterbegin', li);
// или
список.prepend(document.importNode(шаблон.content, true));
список.querySelector('img').setAttribute('src', инпут_с_ссылкой.value);
список.querySelector('h2').innerText = инпут_с_подписью.value;
});
const columns = [ 'name', 'age', 'id' ];
.res.innerHTML = `
<table>
<thead>
<tr>${columns.map(n => `<th>${n}</th>`).join('')}</tr>
</thead>
<tbody>${arr[0]?.map((_, i) => `
<tr>${arr.map(n => `
<td>${n[i]}</td>`).join('')}
</tr>`).join('') ?? ''}
</tbody>
</table>`;
const table = document.createElement('table');
columns.forEach(function(n) {
this.append(document.createElement('th'));
this.lastChild.textContent = n;
}, table.createTHead().insertRow());
arr[0]?.forEach(function(_, i) {
const tr = this.insertRow();
arr.forEach(n => tr.insertCell().textContent = n[i]);
}, table.createTBody());
res.append(table);
data: () => ({
active: [ 0, -1 ],
...
methods: {
onKeyDown(e) {
const { items } = this;
const step = ({
ArrowUp: -1,
ArrowDown: 1,
})[e.key];
if (step && items.some(n => n.children?.length)) {
let iItem = this.active[0];
let iChild = this.active[1] + step;
while (!items[iItem].children?.[iChild]) {
iItem = (iItem + step + items.length) % items.length;
iChild = step === 1 ? 0 : ~-items[iItem].children?.length;
}
this.active = [ iItem, iChild ];
}
},
...
<ul>
<li v-for="(item, iItem) in items">
<ul>
<li
v-for="(child, iChild) in item.children"
:class="{ active: active[0] === iItem && active[1] === iChild }"
...
computed: {
children() {
return this.items.flatMap(n => n.children ?? []);
},
...
data: () => ({
active: null,
...
methods: {
onKeyDown({ key }) {
const { length } = this.children;
const step =
key === 'ArrowUp' ? -1 :
key === 'ArrowDown' ? 1 :
0;
if (step && length) {
const active = this.active ?? (step === 1 ? -1 : length);
this.active = Math.max(0, Math.min(length - 1, active + step));
}
},
...
<ul>
<li v-for="item in items">
<ul>
<li
v-for="child in item.children"
:class="{ active: children[active] === child }"
...