key
. key
. Нужно что-то уникальное, характерное для каждого элемента массива, что не изменится при изменении порядка, скажем.arr.map(el => <TimerComponent name={el} key={el} />)
Ну и массивы в стейте, помните, надо не мутировать, а заменять массив целиком на новый.**
выше остатка от деления %
,3**2 == 9
, уже потом деление по модулю на 7 (остаток == 2) 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 это десять!
name
Например<input type="text" name="first_name" placeholder="First name">
<select name="day_of_week">
<option value="1">Monday</option>
<option value="2">Tuesday</option>
<option value="3">Wednesday</option>
</select>
<?php
$filename = 'form_responses.txt';
if (!empty($_POST)) {
$record = [
// перечисляются поля формы
'first_name' => filter_input(INPUT_POST, 'first_name', FILTER_SANITIZE_STRING),
'day_of_week' => filter_input(INPUT_POST, 'day_of_week', FILTER_SANITIZE_NUMBER_INT),
];
$recordString = implode('; ', $record) . PHP_EOL; // склеить значения через точку с запятой
file_put_contents($filename, $recordString, FILE_APPEND);
}
age
, и возвращать всегда валидное значение.length
у массива reasons
, чтобы он всегда был "пустой". const QA = [
{
q: ['Привет', 'Hi', 'Здарова', 'Ы'],
a: ['Привет', 'Здравствуйте', 'Доброго времени суток'],
},
{
q: ['Как дела?', 'Как жизнь?', 'Как день прошёл?', 'Как настроение?'],
a: ['Хорошо', 'Отлично', 'Лучше всех, надеюсь и у вас так же'],
},
];
q.includes(вопрос)
a
и его случайный элементfunction answer(questionText, QA) {
if (!questionText || questionText.length === 0) {
return 'Пустой вопрос - пустой ответ';
}
const pair = QA.find(pair => pair.q.map(text => text.toLowerCase()).includes(questionText.toLowerCase()));
if (!pair) {
return 'Даже и не знаю, что ответить!..';
}
const randomIndex = Math.floor(Math.random() * pair.a.length);
return pair.a[randomIndex];
}
// использование
answer('Ы', QA); // Привет
for..in
прямо пишут, что порядок детерминирован и одинаков во всех браузерах/движках:The traversal order, as of modern ECMAScript specification, is well-defined and consistent across implementations.
Within each component of the prototype chain, all non-negative integer keys (those that can be array indices) will be traversed first in ascending order by value, then other string keys in ascending chronological order of property creation.
learn.javascript.ru