Практика: парсинг и преобразование
Работа с JSON, URL, query-параметрами.
JSON
const user = { name: 'Алиса', age: 25 };
const json = JSON.stringify(user);
// '{"name":"Алиса","age":25}'
const parsed = JSON.parse(json);
// { name: 'Алиса', age: 25 }
Форматирование:
JSON.stringify(user, null, 2);
Отбор полей:
JSON.stringify(user, ['name'], 2);
// { "name": "Алиса" }
Замена:
JSON.stringify(user, (key, value) =>
key === 'password' ? undefined : value
);
Обработка ошибок парсинга
function safeParse(json) {
try {
return { data: JSON.parse(json), error: null };
} catch (e) {
return { data: null, error: e };
}
}
URLSearchParams
const params = new URLSearchParams('page=1&sort=date');
params.get('page'); // '1'
params.set('page', '2');
params.append('tag', 'js');
params.has('sort'); // true
params.delete('sort');
params.toString(); // 'page=2&tag=js'
Из объекта:
const params = new URLSearchParams({ page: 1, sort: 'date' });
// page=1&sort=date
В объект:
Object.fromEntries(params);
URL
const url = new URL('https://example.com/path?query=1#hash');
url.protocol; // 'https:'
url.host; // 'example.com'
url.pathname; // '/path'
url.search; // '?query=1'
url.hash; // '#hash'
url.searchParams.get('query'); // '1'
Изменение:
url.pathname = '/new';
url.searchParams.set('page', '2');
url.toString();
Query-параметры
function parseQuery(search) {
return Object.fromEntries(new URLSearchParams(search));
}
parseQuery('?page=1&sort=date');
// { page: '1', sort: 'date' }
С приведением типов:
function parseQuery(search, schema = {}) {
const params = Object.fromEntries(new URLSearchParams(search));
const result = {};
for (const [key, value] of Object.entries(params)) {
const type = schema[key];
if (type === 'number') result[key] = Number(value);
else if (type === 'boolean') result[key] = value === 'true';
else result[key] = value;
}
return result;
}
parseQuery('?page=1&active=true', { page: 'number', active: 'boolean' });
// { page: 1, active: true }
Десериализация в класс
class User {
constructor({ name, age }) {
this.name = name;
this.age = age;
}
static fromJSON(json) {
return new User(JSON.parse(json));
}
}
const user = User.fromJSON('{"name":"Алиса","age":25}');
Нормализация
Преобразование массива в словарь:
function normalize(items) {
const byId = {};
const allIds = [];
for (const item of items) {
byId[item.id] = item;
allIds.push(item.id);
}
return { byId, allIds };
}
Обратно:
function denormalize({ byId, allIds }) {
return allIds.map((id) => byId[id]);
}
Денормализация вложенного
function flattenPosts(posts) {
const usersById = {};
const flatPosts = [];
for (const post of posts) {
usersById[post.user.id] = post.user;
flatPosts.push({
...post,
user: undefined,
userId: post.user.id,
});
}
return { posts: flatPosts, usersById };
}
Парсинг CSV
function parseCSV(text) {
const [header, ...rows] = text.trim().split('\n');
const keys = header.split(',');
return rows.map((row) => {
const values = row.split(',');
return Object.fromEntries(keys.map((key, i) => [key, values[i]]));
});
}
Сериализация в query
function buildQuery(params) {
const search = new URLSearchParams();
for (const [key, value] of Object.entries(params)) {
if (value === undefined || value === null || value === '') continue;
if (Array.isArray(value)) {
value.forEach((v) => search.append(key, String(v)));
} else {
search.set(key, String(value));
}
}
return search.toString();
}
buildQuery({ page: 1, tags: ['js', 'react'] });
// 'page=1&tags=js&tags=react'
Итоги
JSON.stringify/parseURLSearchParamsдля queryURLдля разбора адресов- Нормализация для хранилища
- Приведение типов по схеме
- Парсинг CSV вручную