/ Gists / JavaScript

Gists - JavaScript

On gists

BroadCastChannel (sync between 2 tabs immediately)

JavaScript

index.html #

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <button>CLICK ME</button>

        <script>
            const channel = new BroadcastChannel('myChannel');
            document.getElementsByTagName('button')[0].addEventListener('click', e => {
                channel.postMessage('Hello from Tab 1' + new Date().getSeconds);

                console.log('CHANNEL 1');
            });

            channel.onmessage = event => {
                console.log('Message received in Tab 2:', event.data);

                console.log('CHANNEL 2');
            };
        </script>
    </body>
</html>

On gists

JS OOP Design Patterns

JavaScript-OOP JavaScript JS Patterns

patterns.js #

/*

https://blog.carlosrojas.dev/quick-reference-guide-to-design-patterns-in-js-1ebeb1e1c605

*/


/* Singleton */
class Animal {
  constructor() {
    if (typeof Animal.instance === 'object') {
      return Animal.instance;
    }

    Animal.instance = this;

    return this;
  }
}
export default Animal;


/* Prototype */
class Fruit {
  constructor(name, weight) {
    this.name = name;
    this.weight = weight;
  }

  clone() {
    return new Fruit(this.name, this.weight);
  }
}
export default Fruit;

const apple = new Fruit('Apple', 150);
const clonedApple = apple.clone();
console.log(apple);        // Originální ovoce
console.log(clonedApple);  // Klonované ovoce


/* Factory */
class MovieFactory {
  create(genre) {
    if (genre === 'Adventure') return new Movie(genre, 10000);
    if (genre === 'Action') return new Movie(genre, 11000);
  }
}

class Movie {
  constructor(type, price) {
    this.type = type;
    this.price = price;
  }
}
export default MovieFactory;


/* Abstract Factory */
function foodProducer(kind) {
  if (kind === 'protein') return proteinPattern;
  if (kind === 'fat') return fatPattern;
  return carbohydratesPattern;
}

function proteinPattern() {
  return new Protein();
}

function fatPattern() {
  return new Fat();
}

function carbohydratesPattern() {
  return new Carbohydrates();
}

class Protein {
  info() {
    return 'I am Protein.';
  }
}

class Fat {
  info() {
    return 'I am Fat.';
  }
}

class Carbohydrates {
  info() {
    return 'I am carbohydrates.';
  }
}
export default foodProducer;


/* Adapter */
class Soldier {
  constructor(level) {
    this.level = level;
  }

  attack() {
    return this.level * 1;
  }
}

class SuperSoldier {
  constructor(level) {
    this.level = level;
  }

  attackWithShield() {
    return this.level * 10;
  }
}

class SoldierAdapter {
  constructor(superSoldier) {
    this.superSoldier = superSoldier;
  }

  attack() {
    return this.superSoldier.attackWithShield();
  }
}
export { Soldier, SuperSoldier, SoldierAdapter };

// Vytvoření instance SuperSoldier
const superSoldier = new SuperSoldier(5);

// Vytvoření instance SoldierAdapter, který přijímá SuperSoldier jako argument
const soldierAdapter = new SoldierAdapter(superSoldier);

// Volání metody attack() na SoldierAdapteru, která skutečně volá attackWithShield() u SuperSoldiera
const result = soldierAdapter.attack();

console.log(result);  // Vypíše: 50 (5 * 10)



/* Bridge */


class Soldier {
  constructor(weapon) {
    this.weapon = weapon;
  }
}

class SuperSoldier extends Soldier {
  constructor(weapon) {
    super(weapon);
  }

  attack() {
    return 'SuperSoldier, Weapon: ' + this.weapon.get();
  }
}

class IronMan extends Soldier {
  constructor(weapon) {
    super(weapon);
  }

  attack() {
    return 'Ironman, Weapon: ' + this.ink.get();
  }
}

class Weapon {
  constructor(type) {
    this.type = type;
  }

  get() {
    return this.type;
  }
}

class Shield extends Weapon {
  constructor() {
    super('shield');
  }
}

class Rocket extends Weapon {
  constructor() {
    super('rocket');
  }
}
export { SuperSoldier, IronMan, Shield, Rocket };

// Vytvoření instancí zbraní
const shield = new Shield();
const rocket = new Rocket();

// Vytvoření instancí vojáků s různými zbraněmi
const superSoldier = new SuperSoldier(shield);
const ironMan = new IronMan(rocket);

// Útoky vojáků
console.log(superSoldier.attack());  // Vypíše: SuperSoldier, Weapon: shield
console.log(ironMan.attack());       // Vypíše: Ironman, Weapon: rocket


/* Composite */
//Equipment
class Equipment {
  getPrice() {
    return this.price || 0;
  }

  getName() {
    return this.name;
  }

  setName(name) {
    this.name = name;
  }
}

class Pattern extends Equipment {
  constructor() {
    super();
    this.equipments = [];
  }

  add(equipment) {
    this.equipments.push(equipment);
  }

  getPrice() {
    return this.equipments
      .map(equipment => {
        return equipment.getPrice();
      })
      .reduce((a, b) => {
        return a + b;
      });
  }
}

class Cabbinet extends Pattern {
  constructor() {
    super();
    this.setName('cabbinet');
  }
}

// --- leafs ---
class FloppyDisk extends Equipment {
  constructor() {
    super();
    this.setName('Floppy Disk');
    this.price = 70;
  }
}

class HardDrive extends Equipment {
  constructor() {
    super();
    this.setName('Hard Drive');
    this.price = 250;
  }
}

class Memory extends Equipment {
  constructor() {
    super();
    this.setName('Memory');
    this.price = 280;
  }
}

export { Cabbinet, FloppyDisk, HardDrive, Memory };

// Vytvoření jednotlivých listových tříd (FloppyDisk, HardDrive, Memory)
const floppyDisk = new FloppyDisk();
const hardDrive = new HardDrive();
const memory = new Memory();

// Vytvoření skříně a přidání jednotlivých listových tříd do skříně
const cabbinet = new Cabbinet();
cabbinet.add(floppyDisk);
cabbinet.add(hardDrive);
cabbinet.add(memory);

// Získání celkové ceny skříně
const totalPrice = cabbinet.getPrice();
console.log(`Total Price: ${totalPrice}`);  // Vypíše: Total Price: 600


/* Decorator */
class Notification {
  constructor(kind) {
    this.kind = kind || "Generic";
  }
  
  getInfo() {
    return `I'm a ${this.kind} Notification`;
  }
}

class FacebookNotification extends Notification {
  constructor() {
    super("Facebook");
  }
  
  setNotification(msg) {
    this.message = msg;
  }
  
  getInfo() {
    return `${super.getInfo()} with the message: ${this.message}`;
  }
}

class SMSNotification extends Notification {
  constructor() {
    super("SMS");
  }
  
  getInfo() {
    return super.getInfo();
  }
}
export { FacebookNotification, SMSNotification };

// Vytvoření instance SMSNotification
const smsNotification = new SMSNotification();
// Dekorace SMSNotification pomocí FacebookNotificationDecorator
const decoratedNotification = new FacebookNotificationDecorator(smsNotification);
// Získání informací o dekorované notifikaci
console.log(decoratedNotification.getInfo());
// Vypíše: I'm a SMS Notification decorated with Facebook feature


/* Facade */
class Cart {
  constructor() {
    this.discount = new Discount();
    this.shipping = new Shipping();
    this.fees = new Fees();
  }

  calc(price) {
    price = this.discount.calc(price);
    price = this.fees.calc(price);
    price += this.shipping.calc();

    return price;
  }
}

class Discount {
  calc(value) {
    return value * 0.85;
  }
}

class Shipping {
  calc() {
    return 500;
  }
}

class Fees {
  calc(value) {
    return value * 1.1;
  }
}

export default Cart;


/* FlyWeight */
class Ingredient {
  constructor(name) {
    this.name = name;
  }
  
  getInfo() {
    return `I'm a ${this.name}`
  }
}

class Ingredients {
  constructor() {
    this.ingredients = {};
  }

  create(name) {
    let ingredient = this.ingredients[name];
    if (ingredient) return ingredient;

    this.ingredients[name] = new Ingredient(name);

    return this.ingredients[name];
  }
}
export { Ingredients };


/* Proxy */
class Plane {
  fly() {
    return 'flying';
  }
}

class PilotProxy {
  constructor(pilot) {
    this.pilot = pilot;
  }

  fly() {
    return this.pilot.age < 18 ? `too young to fly` : new Plane().fly();
  }
}

class Pilot {
  constructor(age) {
    this.age = age;
  }
}

export { Plane, PilotProxy, Pilot };


/* Iterator */
class Iterator {
  constructor(el) {
    this.index = 0;
    this.elements = el;
  }

  next() {
    return this.elements[this.index++];
  }

  hasNext() {
    return this.index < this.elements.length;
  }
}

export default Iterator;

// Importujte váš Iterator
import Iterator from './Iterator';

// Vytvořte nějakou kolekci dat (v tomto případě pole).
const collection = ['Prvek 1', 'Prvek 2', 'Prvek 3'];

// Vytvořte instanci Iteratoru, předávejte kolekci jako argument konstruktoru.
const iterator = new Iterator(collection);

// Projděte kolekci pomocí Iteratoru.
while (iterator.hasNext()) {
  const element = iterator.next();
  console.log(element);
}



/* Mediator */

class TrafficTower {
  constructor() {
    this.airplanes = [];
  }

  getPositions() {
    return this.airplanes.map(airplane => {
      return airplane.position.showPosition();
    });
  }
}

class Airplane {
  constructor(position, trafficTower) {
    this.position = position;
    this.trafficTower = trafficTower;
    this.trafficTower.airplanes.push(this);
  }

  getPositions() {
    return this.trafficTower.getPositions();
  }
}

class Position {
  constructor(x,y) {
    this.x = x;
    this.y = y;
  }
  
  showPosition() {
    return `My Position is ${x} and ${y}`;
  }
}

export { TrafficTower, Airplane, Position };

const trafficTower = new TrafficTower();

const airplane1 = new Airplane(new Position(10, 20), trafficTower);
const airplane2 = new Airplane(new Position(30, 40), trafficTower);

// Informovat TrafficTower o pozici letadla.
airplane1.getPositions();

// Získat informace o pozicích ostatních letadel pomocí TrafficTower.
airplane2.getPositions();



/* State */
class OrderStatus {
  constructor(name, nextStatus) {
    this.name = name;
    this.nextStatus = nextStatus;
  }

  next() {
    return new this.nextStatus();
  }
}

class WaitingForPayment extends OrderStatus {
  constructor() {
    super('waitingForPayment', Shipping);
  }
}

class Shipping extends OrderStatus {
  constructor() {
    super('shipping', Delivered);
  }
}

class Delivered extends OrderStatus {
  constructor() {
    super('delivered', Delivered);
  }
}

class Order {
  constructor() {
    this.state = new WaitingForPayment();
  }

  nextPattern() {
    this.state = this.state.next();
  }
}

export default Order;


// Vytvořte instanci objednávky
const order = new Order();

// Zjistěte aktuální stav
console.log(order.state.name); // Výstup: 'waitingForPayment'

// Přejděte na další stav
order.nextPattern();

// Zjistěte nový stav
console.log(order.state.name); // Výstup: 'shipping'

// Přejděte na další stav
order.nextPattern();

// Zjistěte nový stav
console.log(order.state.name); // Výstup: 'delivered'



/* Strategy */
class ShoppingCart {
  constructor(discount) {
    this.discount = discount;
    this.amount = 0;
  }

  checkout() {
    return this.discount(this.amount);
  }

  setAmount(amount) {
    this.amount = amount;
  }
}

function guest(amount) {
  return amount;
}

function regular(amount) {
  return amount * 0.9;
}

function premium(amount) {
  return amount * 0.8;
}

export { ShoppingCart, guest, regular, premium };

// Importujte třídu ShoppingCart a slevové strategie
import { ShoppingCart, guest, regular, premium } from './ShoppingCart';

// Vytvořte instanci nákupního košíku s různými slevovými strategiemi
const cartGuest = new ShoppingCart(guest);
const cartRegular = new ShoppingCart(regular);
const cartPremium = new ShoppingCart(premium);

// Nastavte množství v košíku
cartGuest.setAmount(100);
cartRegular.setAmount(100);
cartPremium.setAmount(100);

// Proveďte platbu s různými slevovými strategiemi
console.log(cartGuest.checkout()); // Výstup: 100 (žádná sleva)
console.log(cartRegular.checkout()); // Výstup: 90 (10% sleva pro běžného zákazníka)
console.log(cartPremium.checkout()); // Výstup: 80 (20% sleva pro prémiového zákazníka)



/* Template */
class Tax {
  calc(value) {
    if (value >= 1000) value = this.overThousand(value);

    return this.complementaryFee(value);
  }

  complementaryFee(value) {
    return value + 10;
  }
}

class VAT extends Tax {
  constructor() {
    super();
  }

  overThousand(value) {
    return value * 1.1;
  }
}

class GST extends Tax {
  constructor() {
    super();
  }

  overThousand(value) {
    return value * 1.2;
  }
}

export { VAT, GST };


// Importujte třídy VAT a GST
import { VAT, GST } from './Tax';

// Vytvořte instanci třídy VAT a provedte výpočet daně
const vatTax = new VAT();
console.log(vatTax.calc(1200)); // Výstup: 1320 (včetně přirážky pro hodnoty nad 1000)

// Vytvořte instanci třídy GST a provedte výpočet daně
const gstTax = new GST();
console.log(gstTax.calc(1200)); // Výstup: 1440 (včetně přirážky pro hodnoty nad 1000)

On gists

Closure (Counter)

JavaScript

closure.js #

function counter() {
  let count = 0;

  return function() {
    count++;
    console.log(count);
  };
}

const increment = counter();
increment(); // Output: 1
increment(); // Output: 2

// OR
function createCounter() {
  let count = 0;

  return {
    increment: function() {
      count++;
    },
    decrement: function() {
      count--;
    },
    getCount: function() {
      return count;
    }
  };
}

const counter = createCounter();
counter.increment();
console.log(counter.getCount()); // Output: 1

On gists

5 ways to create an Object in JavaScript

JavaScript

app.js #

// https://levelup.gitconnected.com/5-ways-to-create-an-object-in-javascript-55d556193ee8

// 1 . Object Literals
const car = {
  make: 'Toyota',
  model: 'Corolla',
  year: 2021
};

console.log(car);


// 2. The new Object() Syntax
const person = new Object();
person.name = 'John';
person.age = 30;
person.isEmployed = true;

console.log(person);


// 3. Constructor Functions
function Smartphone(brand, model, year) {
  this.brand = brand;
  this.model = model;
  this.year = year;
}

const myPhone = new Smartphone('Apple', 'iPhone 13', 2021);
console.log(myPhone);


// 4 The Object.create() Method
const animal = {
  type: 'Animal',
  displayType: function() {
    console.log(this.type);
  }
};

const dog = Object.create(animal);
dog.type = 'Dog';
dog.displayType(); // Output: Dog


//  ES6 Class Syntax
class Book {
  constructor(title, author, year) {
    this.title = title;
    this.author = author;
    this.year = year;
  }

  getSummary() {
    return `${this.title} was written by ${this.author} in ${this.year}`;
  }
}

const myBook = new Book('1984', 'George Orwell', 1949);
console.log(myBook.getSummary());

On gists

OOP JS Class - static properties

JavaScript-OOP JavaScript

static.js #

class Item {
	
  static count = 0
  static count2 = 0
	
  constructor(name) {
    this.name = name
    this.constructor.count++
	Item.count2++
	
	console.log(this)
	console.log('-----------------------------------------')
	console.log(this.constructor)
  }

  
  static getCount() {
    return Item.count
  }

  static getCount2() {
    return Item.count2
  }
}


let A = new Item("A");
let B = new Item("B");

/*
console.log(A.getCount()) // nelze
console.log(B.getCount2()) // nelze
*/

console.log(Item.getCount()) // 2
console.log(Item.getCount2()) // 2



/*


[object Object] {
  name: "A"
}

"-----------------------------------------"

class Item {
  
static count = 0
static count2 = 0
  
constructor(name) {
  this.name = name
  this.constructor.count++
  Item.count2++
  
  window.runnerWindow.proxyConsole.log(this)
  window.runnerWindow.proxyConsole.log('-----------------------------------------')
  window.runnerWindow.proxyConsole.log(this.constructor)
}


*/

On gists

JS Mixins (Traits)

JavaScript-OOP JavaScript

Js-mixins.js #

let sayHiMixin = {
  sayHi() {
    alert(`Hello ${this.name}`);
  }
}


let sayByeMixin = {
  sayBye() {
    alert(`Bye ${this.name}`);
  }
}


class User {
  constructor(name) {
    this.name = name;
  }
}

// copy the methods
Object.assign(User.prototype, sayHiMixin);
Object.assign(User.prototype, sayByeMixin);


const user = new User("Dude")

user.sayHi()
user.sayBye()

On gists

Better prev/next index in array

JavaScript Vue.js

app.js #

// after our data inside the Vue instance
  computed: {
    currentImage () {
      return images[this.currentImageIndex]
    },
    previousImageIndex () {
      return (this.currentImageIndex - 1 + images.length) % images.length
    },
    previousImage () {
      return images[this.previousImageIndex]
    },
    nextImageIndex () {
      return (this.currentImageIndex+1) % images.length
    },
    nextImage () {
      return images[this.nextImageIndex]
    },
  }

On gists

Sum column - zylacup sankce

JavaScript ES 6

sum.js #

// MUJ :D
Array.from(document.querySelector('.default').querySelectorAll('tr')).reduce((acc, tr) => {
    let num = parseInt(tr.children[5].textContent)
    if (!isNaN(num)) {
        return acc + num
    }
    return acc
}, 0)

// GPT
const total = [...document.querySelectorAll('.default tr')]
  .map(tr => parseInt(tr.children[5].textContent))
  .filter(num => !isNaN(num))
  .reduce((acc, num) => acc + num, 0);
  

// Variants 
let total = 0;
document.querySelectorAll('.default tr').forEach(tr => {
    let num = parseInt(tr.children[5].textContent);
    if (!isNaN(num)) {
        total += num;
    }
});



const total = [...document.querySelectorAll('.default tr')].reduce((acc, tr) => {
    const num = parseInt(tr.children[5].textContent);
    return !isNaN(num) ? acc + num : acc;
}, 0);



const total = [...document.querySelectorAll('.default tr')].reduce((acc, tr) =>
    acc + (parseInt(tr.children[5].textContent) || 0), 0);
    
    
    
const total = [...document.querySelectorAll('.default tr')].reduceRight((acc, tr) => {
    const num = parseInt(tr.children[5].textContent);
    return !isNaN(num) ? acc + num : acc;
}, 0);

On gists

array reduce - advanced use

JavaScript ES 6

array-reduce.js #

/*
  Resources:
  - https://javascript.plainenglish.io/10-reduce-techniques-worth-mastering-97dd9b9a9e90
  - https://andepaulj.medium.com/javascript-reduce-79aab078da23
  - https://javascript.plainenglish.io/5-use-cases-for-reduce-in-javascript-61ed243b8fef
  - https://code.tutsplus.com/5-real-life-uses-for-the-javascript-reduce-method--cms-39096a
*/

const fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];
const count = fruits.reduce((accumulator, currentValue) => {
  accumulator[currentValue] = (accumulator[currentValue] || 0) + 1;
  return accumulator;
}, {});
console.log(count); // Output: { apple: 3, banana: 2, orange: 1 }


/* Counting Occurrences */
const fruits = [ 'Banana', 'Orange', 'Apple', 'Orange', 'Pear', 'Banana']
const occurrences = fruits.reduce((acc, currFruit) => {
    return {...acc, [currFruit]: (acc[currFruit] || 0) + 1 }
}, {})
console.log(occurrences)
/* 
{ 
Apple: 1, 
Banana: 2, 
Orange: 2, 
Pear: 1 
} 
*/

// OR
const reduceOccurrences = manyNumbers.reduce((acc, cur) => {
  acc[cur] ? acc[cur]++ : acc[cur] = 1
  return acc
}, {})

// OR via Map()
const count = (array) =>
    array.reduce(
        (acc, it) => (acc.set(it, (acc.get(it) || 0) + 1), acc),
        new Map()
    );
const array = [1, 2, 1, 2, -1, 0, "0", 10, "10"];
console.log(count(array));




/* Flatten a List of Arrays */
const arrOfArrs = [
    ['aaron', 'ake', 'anna', 'aje'],
    ['becky', 'ben', 'bright'],
    ['cara', 'chris'],
    ['david', 'daniel', 'danielle', 'djenue'],
]
const flattened = arrOfArrs.reduce((acc, array) => acc.concat(array))
console.log(flattened)
// ["aaron", "ake", "anna", "aje", "becky", "ben", "bright", "cara", "chris", "david", "daniel", // "danielle", "djenue"]

// OR
const array = [1, [2, [3, [4, [5]]]]];
const flat = (arrayNumbers) =>
    arrayNumbers.reduce(
        (acc, it) => acc.concat(Array.isArray(it) ? flat(it) : it),
        []
    );
const flatArray = flat(array);
console.log(flatArray); // [ 1, 2, 3, 4, 5 ]



/* Getting Max and Min Values */
const students = [
    { name: "Kingsley", score: 70 },
    { name: "Jack", score: 80 },
    { name: "Joe", score: 63 },
    { name: "Beth", score: 75 },
    { name: "Kareem", score: 59 },
    { name: "Sarah", score: 93 }
]
const max = students.reduce((acc, student) => {
    if(acc === null || student.score > acc) 
        return student.score
    return acc
}, null)
console.log(max) // Prints 93

// OR
const getMax = (array) => array.reduce((max, num) => (max > num ? max : num));
const getMin = (array) => array.reduce((max, num) => (max < num ? max : num));



/* Converting Between Types */ 
const studentsArray = [
    { name: "Kingsley", score: 70, position: "1st" },
    { name: "Jack", score: 80, position: "2nd" },
    { name: "Joe", score: 63, position: "3rd" },
    { name: "Beth", score: 75, position: "4rd" },
    { name: "Kareem", score: 59, position: "5th" },
    { name: "Sarah", score: 93, position: "6th" }
]
const studentObj = studentsArray.reduce((acc, student) => {
	return {...acc, [student.name]: student.position}
}, {})
console.log(studentObj)
/* 
{ 
Beth: "4rd", 
Jack: "2nd", 
Joe: "3rd", 
Kareem: "5th", 
Kingsley: "1st", 
Sarah: "6th" 
} 
*/



/* Grouping objects by a property */
const result = [
    {subject: 'Physics', marks: 41},
    {subject: 'Chemistry', marks: 59},
    {subject: 'Pure Maths', marks: 36},
    {subject: 'Applied Maths', marks: 90},
    {subject: 'English', marks: 64},
];

let initialValue = {
    pass: [], 
    fail: []
}

const groupedResult = result.reduce((accumulator, current) => {
    (current.marks>=50) ? accumulator.pass.push(current) : accumulator.fail.push(current);
    return accumulator;
}, initialValue);

console.log(groupedResult);
/*
{
 pass: [
  { subject: ‘Chemistry’, marks: 59 },
  { subject: ‘Applied Maths’, marks: 90 },
  { subject: ‘English’, marks: 64 }
 ],
 fail: [
  { subject: ‘Physics’, marks: 41 },
  { subject: ‘Pure Maths’, marks: 36 }
 ]
}
*/




/* Reduce is a Higher-Order Function*/
const plusTwoReducer = (acc, cur) => {
  acc.push(cur + 2)
  return acc
}

const plusSixReducer = (acc, cur) => {
  acc.push(cur + 6)
  return acc
}

numbers.reduce(plusTwoReducer, [])
numbers.reduce(plusSixReducer, [])





On gists

Converting an Array of Objects to an Object

JavaScript ES 6

convert.js #

// https://medium.com/@Evelyn.Taylor/rewriting-javascript-converting-an-array-of-objects-to-an-object-7aeaed399017

const people = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
];

=>

{
  1: 'Alice',
  2: 'Bob',
  3: 'Charlie'
}


// traditional
const peopleObject = {};

for (const person of people) {
  peopleObject[person.id] = person.name;
}

console.log(peopleObject); // {1: 'Alice', 2: 'Bob', 3: 'Charlie'}



// better
const peopleObject = people.reduce((acc, person) => {
  acc[person.id] = person.name;
  return acc;
}, {});

console.log(peopleObject); // {1: 'Alice', 2: 'Bob', 3: 'Charlie'}



// maybe better, maybe less readable, shorter
const peopleObject = people.reduce((acc, { id, name }) => ({ ...acc, [id]: name }), {});