function objToString(val, tabSize = 2, depth = 0, noIndent = false) {
const indent = ' '.repeat(tabSize * depth);
return (noIndent ? '' : indent) + (
val instanceof Array
? `[\n${val.map(n => objToString(n, tabSize, depth + 1)).join(',\n')}\n${indent}]`
: val instanceof Object
? `{\n${Object
.entries(val)
.map(n => n.map((m, i) => objToString(m, tabSize, depth + 1, i)).join(': '))
.join(',\n')}\n${indent}}`
: typeof val === 'string'
? `"${val}"`
: val
);
}
console.log(objToString({
numbers: [ 69, 187, 666 ],
strings: [ 'hello, world!!', 'fuck the world', 'fuck everything' ],
falsy_values: [ 0, '', NaN, false, null, undefined ],
object: { xxx: true, yyy: Infinity, zzz: { '!&$': [ [ [ -1 ] ] ] } }
}));
const result = unique(arr, n => n.user.id);
.const unique = (arr, key) =>
Object.values(Object.fromEntries(arr.map(n => [ key(n), n ])));
// или, если в результирующий массив должны попадать те из "одинаковых" элементов,
// что расположены в исходном массиве первыми
const unique = (arr, key) =>
Object.values(arr.reduce((acc, n) => (acc[key(n)] ??= n, acc), {}));
// или, если надо также сохранять взаимное расположение элементов
const unique = (arr, key) =>
arr.filter(function(n) {
const k = key(n);
return !(this[k] = this.hasOwnProperty(k));
}, {});
Map
и Set
:const unique = (arr, key) =>
Array.from(new Map(arr.map(n => [ key(n), n ])), n => n[1]);
// или (в отличие от объекта, Map запоминает порядок вставки,
// так что тут взаимное расположение элементов сохраняется)
const unique = (arr, key) =>
[...arr.reduce((acc, n) => {
const k = key(n);
return acc.set(k, acc.get(k) ?? n);
}, new Map).values()];
// или
const unique = (arr, key) =>
arr.filter(function(n) {
const k = key(n);
return !this.has(k) && this.add(k);
}, new Set);
const newArr = Object
.values(arr.reduce((acc, n, i) => ((acc[n] ??= []).push(i), acc), {}))
.reduce((acc, n) => (n.forEach(i => acc[i] = n.length > 1), acc), []);
// или
const newArr = arr.map(function(n) {
return this[n];
}, arr.reduce((acc, n) => (acc[n] = acc.hasOwnProperty(n), acc), {}));
// или
const count = arr.reduce((acc, n) => (acc[n] = (acc[n] ?? 0) + 1, acc), {});
const newArr = arr.map(n => count[n] > 1);
// или
const newArr = arr.map((n, i, a) => a.indexOf(n) !== a.lastIndexOf(n));
arr.forEach(function(n, i, a) {
a[i] = this.get(n) > 1;
}, arr.reduce((acc, n) => acc.set(n, -~acc.get(n)), new Map));
// или
const duplicates = arr.reduce((acc, n) => acc.set(n, acc.has(n)), new Map);
arr.splice(0, arr.length, ...arr.map(n => duplicates.get(n)));
// @ , также известный как оператор подавления ошибок -- сразу на мороз.
ini_set( 'upload_max_size' , '400M' ); // -- на мороз. Правильное написание: upload_max_filesize ; переопределяется только через .htaccess (в случае Apache, и если разрешены изменения в .htaccess) или через настройки сервера (PHP_INI_PERDIR), или в php.ini
ini_set( 'post_max_size', '400M'); // -- на мороз. Только через (см. выше.)
ini_set( 'max_execution_time', '300' ); // и это если хватит 300 секунд на обработку потока
const sendRequests = (urls, max) =>
new Promise(resolve => {
const results = Array(urls.length).fill(null);
let countRequests = 0;
let countResponses = 0;
for (let i = 0; i < Math.max(1, Math.min(max, urls.length)); i++) {
request();
}
function request() {
if (countResponses === urls.length) {
resolve(results);
} else if (countRequests < urls.length) {
const index = countRequests++;
fetch(urls[index])
.then(result => result.json())
.catch(error => error)
.then(result => {
results[index] = result;
countResponses++;
request();
});
}
}
});
const blob = new Blob(["The content of the txt file."], {type: "text/plain"});
const blobUrl = URL.createObjectURL(blob);
const a = document.createElement("a");
a.download = "filename.txt";
a.href = blobUrl;
a.click();
setTimeout(() => URL.revokeObjectURL(blobUrl), 10_000);