javascript
examples
examples.js⚡javascript
/**
* 10.7 Object.fromEntries and Advanced Object Methods - Examples
*/
// ============================================
// OBJECT.FROMENTRIES() BASICS
// ============================================
console.log('=== Object.fromEntries Basics ===');
// From array of pairs
const entries = [
['name', 'John'],
['age', 30],
['city', 'NYC'],
];
const obj = Object.fromEntries(entries);
console.log('From entries:', obj);
// From Map
const map = new Map([
['a', 1],
['b', 2],
['c', 3],
]);
const objFromMap = Object.fromEntries(map);
console.log('From Map:', objFromMap);
// Roundtrip: entries -> fromEntries
const original = { x: 10, y: 20, z: 30 };
const roundtrip = Object.fromEntries(Object.entries(original));
console.log('Roundtrip:', roundtrip);
// ============================================
// TRANSFORM PATTERN
// ============================================
console.log('\n=== Transform Pattern ===');
const prices = { apple: 1.5, banana: 0.75, orange: 2.0, mango: 3.5 };
// Double all prices
const doubled = Object.fromEntries(
Object.entries(prices).map(([key, value]) => [key, value * 2])
);
console.log('Doubled:', doubled);
// Apply discount
const discounted = Object.fromEntries(
Object.entries(prices).map(([key, value]) => [key, +(value * 0.9).toFixed(2)])
);
console.log('10% off:', discounted);
// Filter expensive items
const expensive = Object.fromEntries(
Object.entries(prices).filter(([, value]) => value > 1)
);
console.log('Expensive (>$1):', expensive);
// Transform keys to uppercase
const upperKeys = Object.fromEntries(
Object.entries(prices).map(([key, value]) => [key.toUpperCase(), value])
);
console.log('Upper keys:', upperKeys);
// ============================================
// URL QUERY STRING PARSING
// ============================================
console.log('\n=== URL Query String ===');
function parseQueryString(qs) {
return Object.fromEntries(new URLSearchParams(qs));
}
const params = parseQueryString('name=John&age=30&city=New+York&active=true');
console.log('Parsed params:', params);
// Build query string from object
function toQueryString(obj) {
return new URLSearchParams(Object.entries(obj)).toString();
}
console.log('To query:', toQueryString({ search: 'hello', page: 2 }));
// ============================================
// SWAP KEYS AND VALUES
// ============================================
console.log('\n=== Swap Keys/Values ===');
function swapKeysValues(obj) {
return Object.fromEntries(
Object.entries(obj).map(([key, value]) => [value, key])
);
}
const colorCodes = { red: '#FF0000', green: '#00FF00', blue: '#0000FF' };
const codesToColors = swapKeysValues(colorCodes);
console.log('Swapped:', codesToColors);
// ============================================
// OBJECT.GROUPBY() (ES2024)
// ============================================
console.log('\n=== Object.groupBy ===');
const people = [
{ name: 'Alice', age: 25, department: 'Engineering' },
{ name: 'Bob', age: 30, department: 'Marketing' },
{ name: 'Charlie', age: 25, department: 'Engineering' },
{ name: 'Diana', age: 30, department: 'Engineering' },
{ name: 'Eve', age: 35, department: 'Marketing' },
];
// Check if Object.groupBy exists (ES2024)
if (typeof Object.groupBy === 'function') {
// Group by department
const byDepartment = Object.groupBy(people, (p) => p.department);
console.log('By department:', byDepartment);
// Group by age
const byAge = Object.groupBy(people, (p) => p.age);
console.log('By age:', byAge);
} else {
// Polyfill/manual implementation
function groupBy(array, keyFn) {
return array.reduce((groups, item) => {
const key = keyFn(item);
(groups[key] ??= []).push(item);
return groups;
}, {});
}
const byDepartment = groupBy(people, (p) => p.department);
console.log('By department (polyfill):', byDepartment);
}
// ============================================
// CUSTOM GROUPING LOGIC
// ============================================
console.log('\n=== Custom Grouping ===');
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Polyfill for environments without Object.groupBy
const groupBy = (arr, fn) =>
arr.reduce((acc, item) => {
const key = fn(item);
(acc[key] ??= []).push(item);
return acc;
}, {});
// Group by even/odd
const byParity = groupBy(numbers, (n) => (n % 2 === 0 ? 'even' : 'odd'));
console.log('By parity:', byParity);
// Group by range
const byRange = groupBy(numbers, (n) => {
if (n <= 3) return 'low';
if (n <= 7) return 'medium';
return 'high';
});
console.log('By range:', byRange);
// Group strings by first letter
const words = ['apple', 'banana', 'apricot', 'blueberry', 'cherry', 'avocado'];
const byFirstLetter = groupBy(words, (w) => w[0].toUpperCase());
console.log('By first letter:', byFirstLetter);
// ============================================
// OBJECT.HASOWN()
// ============================================
console.log('\n=== Object.hasOwn ===');
const user = { name: 'John', age: 30 };
// Compare approaches
console.log('hasOwnProperty:', user.hasOwnProperty('name')); // true
console.log('Object.hasOwn:', Object.hasOwn(user, 'name')); // true
// Object.hasOwn is safer with null prototype objects
const nullProtoObj = Object.create(null);
nullProtoObj.key = 'value';
// nullProtoObj.hasOwnProperty('key'); // Would throw!
console.log('hasOwn on null proto:', Object.hasOwn(nullProtoObj, 'key')); // true
// Inherited vs own
const child = Object.create({ inherited: true });
child.own = 'value';
console.log('own property:', Object.hasOwn(child, 'own')); // true
console.log('inherited:', Object.hasOwn(child, 'inherited')); // false
// ============================================
// PICK AND OMIT UTILITIES
// ============================================
console.log('\n=== Pick and Omit ===');
function pick(obj, keys) {
return Object.fromEntries(
Object.entries(obj).filter(([key]) => keys.includes(key))
);
}
function omit(obj, keys) {
return Object.fromEntries(
Object.entries(obj).filter(([key]) => !keys.includes(key))
);
}
const fullUser = {
id: 1,
name: 'John',
email: 'john@example.com',
password: 'secret123',
role: 'admin',
};
console.log('Pick:', pick(fullUser, ['id', 'name', 'email']));
console.log('Omit:', omit(fullUser, ['password']));
// ============================================
// MAP VALUES AND KEYS
// ============================================
console.log('\n=== Map Values/Keys ===');
function mapValues(obj, fn) {
return Object.fromEntries(
Object.entries(obj).map(([key, value]) => [key, fn(value, key)])
);
}
function mapKeys(obj, fn) {
return Object.fromEntries(
Object.entries(obj).map(([key, value]) => [fn(key, value), value])
);
}
const scores = { math: 85, english: 92, science: 78 };
console.log(
'To percent:',
mapValues(scores, (v) => v + '%')
);
console.log(
'To decimals:',
mapValues(scores, (v) => v / 100)
);
console.log(
'Upper keys:',
mapKeys(scores, (k) => k.toUpperCase())
);
console.log(
'Prefix keys:',
mapKeys(scores, (k) => 'score_' + k)
);
// ============================================
// DEEP TRANSFORM KEYS
// ============================================
console.log('\n=== Deep Transform Keys ===');
function deepTransformKeys(obj, transformer) {
if (Array.isArray(obj)) {
return obj.map((item) => deepTransformKeys(item, transformer));
}
if (obj !== null && typeof obj === 'object') {
return Object.fromEntries(
Object.entries(obj).map(([key, value]) => [
transformer(key),
deepTransformKeys(value, transformer),
])
);
}
return obj;
}
// Snake case to camel case
const snakeToCamel = (str) =>
str.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
// Camel case to snake case
const camelToSnake = (str) =>
str.replace(/[A-Z]/g, (c) => '_' + c.toLowerCase());
const apiResponse = {
user_name: 'john_doe',
user_data: {
birth_date: '1990-01-01',
email_address: 'john@example.com',
phone_numbers: [{ phone_type: 'home', phone_number: '123-456-7890' }],
},
};
const camelCased = deepTransformKeys(apiResponse, snakeToCamel);
console.log('Camel cased:', JSON.stringify(camelCased, null, 2));
// ============================================
// DEFAULTS MERGE
// ============================================
console.log('\n=== Defaults Merge ===');
function defaults(target, ...sources) {
const allEntries = [target, ...sources].flatMap(Object.entries);
const merged = new Map();
for (const [key, value] of allEntries) {
if (!merged.has(key)) {
merged.set(key, value);
}
}
return Object.fromEntries(merged);
}
const options = { timeout: 5000 };
const defaults1 = { timeout: 3000, retries: 3 };
const defaults2 = { retries: 5, cache: true };
console.log('Merged defaults:', defaults(options, defaults1, defaults2));
// ============================================
// INVERT OBJECT
// ============================================
console.log('\n=== Invert Object ===');
function invert(obj) {
return Object.fromEntries(
Object.entries(obj).map(([key, value]) => [String(value), key])
);
}
const statusCodes = {
OK: 200,
Created: 201,
NotFound: 404,
ServerError: 500,
};
console.log('Inverted:', invert(statusCodes));
// ============================================
// PRACTICAL: CONFIGURATION MERGE
// ============================================
console.log('\n=== Configuration Merge ===');
function mergeConfig(defaultConfig, ...overrides) {
const entries = [defaultConfig, ...overrides].flatMap((obj) =>
Object.entries(obj)
);
const result = {};
for (const [key, value] of entries) {
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
result[key] = { ...result[key], ...value };
} else {
result[key] = value;
}
}
return result;
}
const defaultConfig = {
port: 3000,
database: { host: 'localhost', port: 5432 },
logging: true,
};
const envConfig = {
port: 8080,
database: { port: 5433 },
};
console.log('Merged config:', mergeConfig(defaultConfig, envConfig));
// ============================================
// PRACTICAL: OBJECT DIFF
// ============================================
console.log('\n=== Object Diff ===');
function objectDiff(obj1, obj2) {
const keys = new Set([...Object.keys(obj1), ...Object.keys(obj2)]);
const diff = { added: {}, removed: {}, changed: {} };
for (const key of keys) {
if (!(key in obj1)) {
diff.added[key] = obj2[key];
} else if (!(key in obj2)) {
diff.removed[key] = obj1[key];
} else if (obj1[key] !== obj2[key]) {
diff.changed[key] = { from: obj1[key], to: obj2[key] };
}
}
return diff;
}
const before = { a: 1, b: 2, c: 3 };
const after = { a: 1, b: 5, d: 4 };
console.log('Diff:', objectDiff(before, after));
console.log('\n=== Examples Complete ===');