statistic = statistic.map(x=>{
return [x.phone || "",
(x.finishedAt != null) ? new Date(x.finishedAt).toLocaleString("ru-RU", {timeZone: "Europe/Moscow"}) : "",
x.attemptsCount || "",
x.tagName || "",
x.jobStatus || "",
x.callDuration || "",
x.callJobId || "",
x.town || "",
x.fio || ""
];
})
SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName("Лист1") // Имя листа вывода
.getRange(1,1, statistic.length, statistic[0].length) // 1,1 - строка и столбец ячейки вывода
.setValues(statistic);
const newStr = new Date(str.split(' GMT', 1)[0])
.toLocaleDateString('ru-RU')
.split('.')
.reverse()
.join(', ');
const formatDateStr = function(str) {
const [ , month, day, year ] = str.match(/(\S+) (\d+) (\d+)/);
return [ year, this[month], day.padStart(2, 0) ].join(', ');
}.bind(Object.fromEntries(Array.from({ length: 12 }, (_, i) => [
new Date(0, i).toLocaleString('en', { month: 'short' }),
`${i + 1}`.padStart(2, 0)
])));
const newStr = formatDateStr(str);
const averages = Array.from(
arr
.flatMap(v => v.properties.groups)
.reduce((acc, {id, 'well-being': value}) => {
const [count, total] = acc.get(id) ?? [0, 0];
acc.set(id, [count + 1, total + value]);
return acc;
}, new Map())
.entries(),
([id, [count, total]]) => ({id, average: total / count}),
);
console.log(averages);
ws.getRange(2, 1, 1000, ws.getLastColumn()).clearFormat();
//...
"sheets": {
"macros": [{
"menuName": "macros1",
"functionName": "myFunction",
"defaultShortcut": "Ctrl+Shift+Alt+1"
}]
}
//...
function onSelectionChange() {
let ss = SpreadsheetApp.getActiveSpreadsheet();
let as = ss.getActiveSheet();
let ac = as.getActiveCell();
let row = ac.getRow();
as.getRange(row+":"+row).setBackground("yellow");
}
const tree = ref(null)
return {
tree,
...
<el-tree
ref="tree"
...
tree.value.getCheckedKeys()
. async componentDidMount() {
const lastSongsResponse = await fetch("https://api.laut.fm/station/key/last_songs");
const lastSongs = await lastSongsResponse.json();
lastSongs.length = Math.min(7, lastSongs.length);
const promises = lastSongs.map((song) => new Promise((resolve, reject) => {
const params = {
method : 'album.getInfo',
artist : song.artist.name.replace(' & ', ', '),
album : song.album,
api_key : 'apikey',
format : 'json',
};
const url = "https://ws.audioscrobbler.com/2.0/?" + Object.keys(params).map((key) => `${key}=${params[key]}`).join('&');
const cover = await fetch(url)
.then((response) => response.json())
.then((songData) => songData.album.image[4]["#text"])
.catch(err => reject(err));
const date = new Date(song.started_at);
const songData = {
id1 : song.id,
id2 : song.id + 1,
artist : song.artist.name,
title : song.title,
cover : cover,
started_at : date.getHours() + ':' + date.getMinutes().toString().padStart(2, '0')
}
resolve(songData);
}));
const results = await Promise.all(promises);
this.setState({ results: results })
}
const array = [
[
{ name: 'A', age: 10 },
{ name: 'B', age: 10 },
{ name: 'A', age: 10 },
{ name: 'B', age: 10 },
],
[
{ name: 'C', age: 10 },
{ name: 'D', age: 10 },
{ name: 'C', age: 10 },
{ name: 'D', age: 10 },
],
];
const groupBy = (collection, extractKey) => {
const cache = new Map();
return collection.reduce((accumulator, entry) => {
const key = extractKey(entry);
if (!cache.has(key)) {
const group = [];
cache.set(key, group);
accumulator.push(group);
}
cache.get(key).push(entry);
return accumulator;
}, []);
};
const newArray = array.map(entry => groupBy(entry, item => item.name));
console.log(newArray);
/*
[
[
[ { name: 'A', age: 10 }, { name: 'A', age: 10 } ],
[ { name: 'B', age: 10 }, { name: 'B', age: 10 } ]
],
[
[ { name: 'C', age: 10 }, { name: 'C', age: 10 } ],
[ { name: 'D', age: 10 }, { name: 'D', age: 10 } ]
]
]
*/
const groupBy = (collection, extractKey) => {
const cache = new Map();
for (const entry of collection) {
const key = extractKey(entry);
if (!cache.has(key)) {
cache.set(key, []);
}
cache.get(key).push(entry);
}
return [...cache.values()];
};
For DOM trees which represent HTML documents, the returned tag name is always in the canonical upper-case form.
if(str.tagName == 'ul') {
} else if (str.tagName == 'li') {
str
, что за странный выбор имени? Там же элемент, а не строка.elem.append('li');
for (let el of strLi) { el.addEventListener('click',func); };
func
вынесено за пределы текущей функции, иначе бы при каждом клике всем существующим li
добавлялся новый обработчик.li
, на свежесозданных li
клик обрабатываться не будет (касается и тех, что изначально существуют).li
- так зачем назначать отдельный обработчик клика? То, что делаете в func
, вполне можно делать прямо тут.document.querySelector('ul').addEventListener('click', e => {
const t = e.target;
const ct = e.currentTarget;
t.insertAdjacentHTML('beforeend', ct === t ? '<li>text</li>' : '!');
});
const form = document.querySelector('.form');
const items = [...form.querySelectorAll('.form__item')];
form.addEventListener('change', function(e) {
const index = items.indexOf(e.target.closest('.form__item'));
form.querySelector('.form__progress-line').style.width = (index + 2) * 100 / items.length + '%';
setTimeout(() => {
items[index]?.classList.remove('form__item--active');
items[index + 1]?.classList.add('form__item--active');
if (index + 1 === items.length) {
form.style.display = 'none';
document.querySelector('.result').classList.add('result--active');
}
}, 1000);
});
form.dispatchEvent(new Event('change'));
let arr = [
{city: 'Москва', address: 'адрес 1'},
{city: 'Москва', address: 'адрес 2'},
{city: 'Петербург', address: 'адрес 3'},
{city: 'Москва', address: 'адрес 4'},
]
[...new Set(arr.map(item => item.city))].map(function(item) {
return {city: item, address: arr.filter(itm => itm.city == item).map(itm => itm.address)}
})
const group = (arr, idKey, valKey) =>
Object.values(arr.reduce((acc, { [idKey]: id, [valKey]: val }) => (
(acc[id] = acc[id] ?? { [idKey]: id, [valKey]: [] })[valKey].push(val),
acc
), {}));
const groupedAddresses = useMemo(() => {
return group(addresses, 'city', 'address');
}, [ addresses ]);
<ul>
{groupedAddresses.map(n => (
<li>
<h3>{n.city}</h3>
<ul>{n.address.map(m => <li>{m}</li>)}</ul>
</li>
))}
</ul>