arr
нужна только внутри цикла, лучше её туда и поместить. В большом коде проще будет разобраться, когда ограничена область видимости созданных переменных. const
вместо let
уместнее, т.к. внутри цикла значение key
не меняется, да и arr
тоже:for (const key in a14) {
const arr = a14[key];
// ...
}
.join(' ')
– это избавляет от проблемы лишнего пробела, да и innerHTML
лучше innerText
, т.к. выводимое не содержит разметки, и зачем заставлять браузер пытаться разбирать его как HTML.- document.querySelector('.b-14').onclick = f14;
+ document.querySelector('.b-14').addEventListener('click', f14);
a14
, то может, слышали про Object.values().const f14 = () => document.querySelector('.out-14') // элемент для вывода результата
.innerText = Object.values(a14) // массив массивов [ [1, 2, 23], [3, 4, 5], ... ]
.map(arr => arr[0]) // вместо каждого под-массива, его первый элемент
.join(' '); // склеить в строку через пробел
random(6)
возвращает целое: 1, 2, 3, 4, 5 или 6 – с равной вероятностью.(1 + 1 + 1 + 1 + 1 + 1) / 6 == 1
1/6 * 1/6 * 1/6 * 1/6 * 1/6 * 1/6 = 1 / 6^6 = 0,00002143347051
= 2 тысячные процента. Всего ничего. [[1, 2, 3],[4, 5, 6],[7, 8, 9]].map(arr => arr.reduce((acc, c) => acc + c))
// [ 6, 15, 24 ]
[
[1, 2, 3] --> 6
[4, 5, 6] --> 15
[7, 8, 9] --> 24
]
— это операция map(): каждый-в-каждый.reduce( (accumulator, current) => accumulator + current )
reduce(
function(accumulator, current) {
return accumulator + current;
}
)
data.map(({ day, ...rest }) => {
const quarter = ['I', 'II', 'III', 'IV'][Math.floor((+day.substring(5, 7) - 1) / 3)];
const year = day.substring(0, 4);
const hash = `${year}-${quarter}`; // "2022-IV"
return { hash, day, ...rest };
})
[
{
"hash": "2021-III",
"day": "2021-07-23T00:00:00",
"speed": 3283,
"distance": 3283,
"wagons": 1
},
{
"hash": "2021-III",
"day": "2021-09-26T00:00:00",
"speed": 1879,
"distance": 1879,
"wagons": 1
},
{
"hash": "2022-I",
"day": "2022-03-11T00:00:00",
"speed": 10372,
"distance": 15558,
"wagons": 3
},
{
"hash": "2022-III",
"day": "2022-07-25T00:00:00",
"speed": 455,
"distance": 455,
"wagons": 1
},
{
"hash": "2022-III",
"day": "2022-09-24T00:00:00",
"speed": 3720.0666666666666,
"distance": 18632,
"wagons": 11
},
{
"hash": "2022-IV",
"day": "2022-10-01T00:00:00",
"speed": 55944.81598981719,
"distance": 1227358,
"wagons": 805
},
{
"hash": "2022-IV",
"day": "2022-11-01T00:00:00",
"speed": 35877.33829052166,
"distance": 6621346,
"wagons": 5528
},
{
"hash": "2022-IV",
"day": "2022-12-01T00:00:00",
"speed": 39757.51849326638,
"distance": 9322141,
"wagons": 7258
},
{
"hash": "2023-I",
"day": "2023-01-01T00:00:00",
"speed": 16726.83149608712,
"distance": 1022607,
"wagons": 794
}
]
const props = ['speed', 'distance', 'wagons'];
const result = data.reduce((acc, c) => {
const yearMonth = c.day.substring(0, 7); // '2022-03'
props.forEach(prop => {
acc[prop][yearMonth] = (acc[prop][yearMonth] ?? 0) + c[prop];
});
return acc;
}, Object.fromEntries(props.map(prop => [prop, {}])));
{
"speed": {
"2022-09": 22452,
"2022-10": 65668.58282444967,
"2022-11": 6397.635863857564
},
"distance": {
"2022-09": 68752,
"2022-10": 1119233,
"2022-11": 289732
},
"wagons": {
"2022-09": 26,
"2022-10": 427,
"2022-11": 176
}
}
const hashMap = data.reduce((acc, { day, ...rest }) => {
const hash = day.substring(0, 7);
if (Object.hasOwn(acc, hash)) {
Object.keys(rest).forEach(prop => acc[hash][prop] += rest[prop]);
} else {
acc[hash] = { day: hash, ...rest };
}
return acc;
}, {});
const result = Object.values(hashMap);
[
{
"day": "2022-09",
"speed": 22452,
"distance": 68752,
"wagons": 26
},
{
"day": "2022-10",
"speed": 65668.58282444967,
"distance": 1119233,
"wagons": 427
},
{
"day": "2022-11",
"speed": 6397.635863857564,
"distance": 289732,
"wagons": 176
}
]
const arr = Array.from(myNodeList);
const text = div.textContent;
function func1() {
// сделать массив с этими дивами
const divs = Array.from(document.querySelectorAll(".data > div"));
// отсортировать, интерпретируя текст как числа
divs.sort((a, b) => +b.textContent - +a.textContent);
// куда их всех переставлять
const result = document.querySelector(".result");
// пока в массиве что-то есть, берём последний и вставляем в result
while(divs.length) {
result.appendChild(divs.pop());
}
}
func1();
const formatter = new Intl.DateTimeFormat('ru-RU', {
dateStyle: 'long',
timeStyle: 'short',
});
const date = new Date('2023-01-12T07:00:03Z');
formatter.format(date)
// "12 января 2023 г., 10:00"
в то время как в Лондоне 7 утра, в Москве 10:00 (в часовом поясе браузера) input:required
и select:required
можно выбрать все инпуты с атрибутом required
.radio
достаточно указать required
у первого элемента.select
опции-затычке надо указать value=""
и добавить атрибуты disabled hidden selected
, чтобы такая опция не считалась заполнением.element.validity.valueMissing
:true
означает пустоту обязательного поля. Когда не все поля валидны, то preventDefault()
событию предотвратит переключение таба.const output = Object.fromEntries(Object.values(obj).map(name => [name, 0]));
items.forEach(({ id, price }) => {
if (!Object.hasOwn(obj, id)) return;
output[obj[id]] += price;
});
output.total = Object.values(output).reduce((acc, c) => acc + c);
// { first: 80000, second: 80000, total: 160000 }
const obj = {
_x: 0,
get x() {
return this._x;
},
set x(value) {
this._x = value;
if (this._x === 5) {
console.log('Пятёрочка!');
}
},
};
// использование
obj.x = 5; // Пятёрочка!
const obj = {
_x: 0,
_filters: {},
addFilter(value, callback) {
this._filters[value] = callback;
},
get x() {
return this._x;
},
set x(value) {
this._x = value;
this._filters[value]?.(value);
},
};
// добавить обработчики
obj.addFilter(5, () => console.log('Пятёрочка!'));
obj.addFilter(10, v => console.log(`${v} это десять!`));
// использование
obj.x = 10; // 10 это десять!