const SORT = [
[ 'без сортировки' ],
[ 'цена, по возрастанию', (a, b) => a.price - b.price ],
[ 'цена, по убыванию', (a, b) => b.price - a.price ],
[ 'год создания, по возрастанию', (a, b) => a.formed_in - b.formed_in ],
[ 'год создания, по убыванию', (a, b) => b.formed_in - a.formed_in ],
];
const [ sortType, setSortType ] = useState(0);
const data = useMemo(() => {
const sortFunc = SORT[sortType][1];
return sortFunc ? [...bands].sort(sortFunc) : bands;
}, [ bands, sortType ]);
<select value={sortType} onChange={e => setSortType(e.target.value)}>
{SORT.map((n, i) => <option value={i}>{n[0]}</option>)}
</select>
const [ author, setAuthor ] = useState(null);
const [ dateMin, setDateMin ] = useState(null);
const [ dateMax, setDateMax ] = useState(null);
const authors = useMemo(
() => [...new Set(articles.map(n => n.author))],
[ articles ]
);
const filteredArticles = useMemo(
() => [
[ author, n => n.author === author ],
[ dateMin, n => n.publishedAt >= dateMin ],
[ dateMax, n => n.publishedAt <= dateMax ],
].reduce((acc, n) => n[0] ? acc.filter(n[1]) : acc, articles),
[ articles, author, dateMin, dateMax ]
);
<select value={author} onChange={e => setAuthor(e.target.value)}>
<option></option>
{authors.map(n => <option>{n}</option>)}
</select>
от <input type="date" value={dateMin} onChange={e => setDateMin(e.target.value)} />
до <input type="date" value={dateMax} onChange={e => setDateMax(e.target.value)} />
{filteredArticles.map(n => <Card {...n} />)}
data: () => ({
handle: null,
...
}),
mounted() {
const mql = matchMedia('(max-width: 768px)');
const onChange = () => this.handle = mql.matches ? '.image' : null;
onChange();
mql.addEventListener('change', onChange);
this.$on('hook:beforeDestroy', () => mql.removeEventListener('change', onChange));
},
<draggable
:options="{ handle, ... }"
...
>
arr.sort((a, b) => a.surname.localeCompare(b.surname) || a.name.localeCompare(b.name));
const sorted = (arr, keys) => arr
.map(n => [ n ].concat(keys(n)))
.sort((a, b) => {
let diff = 0;
a.find((n, i) => diff = i && ((n < b[i]) ? -1 : +(n > b[i])));
return diff;
})
.map(n => n[0]);
const sortedArr = sorted(arr, n => [ n.surname.toLowerCase(), n.name.toLowerCase() ]);
computed: {
deadlineText() {
const today = new Date().setHours(0, 0, 0, 0);
const deadline = new Date(this.task.deadline).setHours(0, 0, 0, 0);
return [ 'Уже было', 'Сегодня', 'Жди' ][1 + Math.sign(deadline - today)];
},
},
const [ autoplay, setAutoplay ] = useState(false);
const swiper = useRef();
useEffect(() => {
swiper.current.autoplay[autoplay ? 'start' : 'stop']();
}, [ autoplay ]);
<input
type="checkbox"
checked={autoplay}
onChange={e => setAutoplay(e.target.checked)}
/>
<Swiper
onSwiper={instance => swiper.current = instance}
...
>
selects[0].appendChild(option) selects[1].appendChild(option)
Если данный дочерний элемент является ссылкой на существующий узел в документе, то функция appendChild()
перемещает его из текущей позиции в новую позицию
selects[1].appendChild(option.cloneNode(true));
selects.forEach(function(n) {
n.append(...this.map(m => new Option(m[1].label, m[0])));
}, Object.entries(metrics.convertRules));
const optionsHTML = Object
.entries(metrics.convertRules)
.map(n => `<option value="${n[0]}">${n[1].label}</option>`)
.join('');
selects.forEach(n => n.innerHTML = optionsHTML);
data: () => ({
selected: [ null, null, null ],
...
}),
computed: {
selectData() {
const data = Array.from({ length: this.selected.length }, () => []);
for (let { items } = this.selectors, i = 0; items && i < data.length; i++) {
data[i] = items;
items = items.find(n => n.value === this.selected[i])?.childs;
}
return data;
},
...
},
methods: {
resetSelected(index) {
for (let i = index; i < this.selected.length; i++) {
this.selected[i] = null;
}
},
...
},
<v-col v-for="(n, i) in selected" cols="4">
<v-select
:items="selectData[i]"
item-text="title"
item-value="value"
v-model="selected[i]"
@change="resetSelected(i + 1)"
></v-select>
</v-col>
document.addEventListener('input', e => {
if (e.target.classList.contains('form-control')) {
const form = e.target.closest('селектор формы');
form.querySelector('span').innerText = Array
.from(form.querySelectorAll('input.form-control'))
.reduce((acc, n) => acc * (+n.value || 0), 1);
}
});
$result = array_sum(array_filter(
array_count_values($all_items),
fn($n) => in_array($n, $filters),
ARRAY_FILTER_USE_KEY
));
$result = count(array_intersect($all_items, $filters));
const data = Object.entries(сюда кидаете свои данные);
const years = Array
.from(new Set(data.flatMap(n => Object.keys(n[1].G))))
.sort((a, b) => a - b);
const columns = Array
.from(new Set(data.flatMap(n => Object.values(n[1].G).flatMap(Object.keys))))
.sort();
<TableHead>
<TableRow>
<TableCell rowSpan={2}>regions</TableCell>
{years.map(n => <TableCell colSpan={columns.length}>{n}</TableCell>)}
</TableRow>
<TableRow>
{years.flatMap(n => columns.map(m => <TableCell>{m}</TableCell>))}
</TableRow>
</TableHead>
<TableBody>
{data.map(([ region, { G } ]) => (
<TableRow>
<TableCell>{region}</TableCell>
{years.flatMap(n => columns.map(m => <TableCell>{G[n]?.[m]?.value ?? 0}</TableCell>))}
</TableRow>
))}
</TableBody>
null
. В стек сохраняем индекс, под которым добавленная пара оказалась в массиве с результатами.null
на индекс встреченной скобки. Конечно, если в стеке что-то есть. Если стек пустой - значит, у встреченной закрывающей скобки не было соответствующей ей открывающей, добавляем в результирующий массив пару из null
и текущего индекса.function bracketIndices(str) {
const stack = [];
const result = [];
for (let i = 0; i < str.length; i++) {
if (str[i] === '{') {
stack.push(result.push([ i, null ]) - 1);
} else if (str[i] === '}') {
if (stack.length) {
result[stack.pop()][1] = i;
} else {
result.push([ null, i ]);
}
}
}
return result;
}
bracketIndices('{}{{{}}}') // [[0,1],[2,7],[3,6],[4,5]]
bracketIndices('---}{{}{') // [[null,3],[4,null],[5,6],[7,null]]
bracketIndices('fuck off') // []
arr.reduce((acc, n) => (
n = n.match(/(\S+) = (.*)/),
n && (acc[n[1]] = n[2]),
acc
), {})
Object.fromEntries(arr
.map(n => n.split(': ').pop().split(' = '))
.filter(n => n.length === 2)
)
const plusSelector = '.count-plus';
const minusSelector = '.count-minus';
function updateCount(el, change) {
const counterEl = el.closest('.count-wrapper').querySelector('.counter');
counterEl.innerText = Math.max(0, +counterEl.innerText + change);
}
document.addEventListener('click', ({ target: t }) => {
const change = +t.matches(plusSelector) || -t.matches(minusSelector);
if (change) {
updateCount(t, change);
}
});
function setClickHandler(selector, change) {
document.querySelectorAll(selector).forEach(function(n) {
n.addEventListener('click', this);
}, e => updateCount(e.target, change));
}
setClickHandler(plusSelector, 1);
setClickHandler(minusSelector, -1);
items_dict = {}
for i in range(len(data)):
for n in data[i]['balance']['StringList']['String']:
if n['Code'] not in items_dict:
items_dict[n['Code']] = [ n['Name'], n['Code'], *[ 'None' ] * len(data) ]
items_dict[n['Code']][i + 2] = n['Value']
items_arr = list(items_dict.values())