Immutable array

// Original items array
const items = [
  { id: "uuid-1", title: "Item 1" },
  { id: "uuid-2", title: "Item 2" },
  { id: "uuid-3", title: "Item 3" },
];

// Immutable Delete
const deleteId = "uuid-2";
const itemsAfterDelete = items.filter(item => item.id !== deleteId);

// Immutable Modify
const modifyId = "uuid-3";
const itemsAfterModify = itemsAfterDelete.map(item =>
  item.id === modifyId ? { ...item, title: "Modified Item 3" } : item
);

// Immutable Add
const newItem = { id: "uuid-4", title: "Item 4" };
const itemsAfterAdd = [...itemsAfterModify, newItem];

// Logging for demonstration
console.log(items); // Original items array remains unchanged
console.log(itemsAfterDelete); // Items after deletion
console.log(itemsAfterModify); // Items after modification

console.log(itemsAfterAdd); // Items after adding a new item 

destructuring Map

 // Initialize items as a Map

let items = new Map([
  ["uuid-1", { id: "uuid-1", title: "Item 1" }],
  ["uuid-2", { id: "uuid-2", title: "Item 2" }],
  ["uuid-3", { id: "uuid-3", title: "Item 3" }],
]);

// Delete item with id "uuid-2"
const deleteId = "uuid-2";
const deletedItem = items.get(deleteId); // Get the item to be
deleted (for logging)
items.delete(deleteId); // Delete the item from the Map

console.log(deletedItem); // Log the deleted item
console.log(Array.from(items)); // Convert Map to Array to log remaining items

// modify item with id "uuid-3"
const modifyId = "uuid-3";
const modifiedItem = items.get(modifyId); // Get the item to be modified (for logging)
items.set(modifyId, { ...modifiedItem, title: "Modified Item 3" });
// Modify the item in the Map

console.log(modifiedItem); // Log the modified item
console.log(Array.from(items)); // Convert Map to Array to log remaining items

// Add a new item
const newItem = { id: "uuid-4", title: "Item 4" }; // Create a new item
items.set(newItem.id, newItem); // Add the new item to the Map

console.log(Array.from(items)); // Convert Map to Array to log all items

// MAP IS IMMUTABLE
// Original items Map
const items = new Map([
  ["uuid-1", { id: "uuid-1", title: "Item 1" }],
  ["uuid-2", { id: "uuid-2", title: "Item 2" }],
  ["uuid-3", { id: "uuid-3", title: "Item 3" }],
]);

// Immutable Delete
const deleteId = "uuid-2";
const itemsAfterDelete = new Map([...items].filter(([key, _]) => key !== deleteId));

// Immutable Modify
const modifyId = "uuid-3";
const modifiedItem = { ...items.get(modifyId), title: "Modified Item 3" };
const itemsAfterModify = new Map([...itemsAfterDelete]
.map(([key, value]) => key === modifyId ? [key, modifiedItem] : [key, value]));

// Immutable Add
const newItem = { id: "uuid-4", title: "Item 4" };
const itemsAfterAdd = new Map([...itemsAfterModify, [newItem.id, newItem]]);

// Logging for demonstration
console.log(Array.from(items)); // Original items Map remains unchanged
console.log(Array.from(itemsAfterDelete)); // Items after deletion
console.log(Array.from(itemsAfterModify)); // Items after modification
console.log(Array.from(itemsAfterAdd)); // Items after adding a new item

Destructuring Object

let items = {
  "uuid-1": { id: "uuid-1", title: "Item 1" },
  "uuid-2": { id: "uuid-2", title: "Item 2" },
  "uuid-3": { id: "uuid-3", title: "Item 3" },
};

// Delete item with id "uuid-2"
const deleteId = "uuid-2";
const { [deleteId]: deletedItem, ...remainingItems } = items;
items = remainingItems; // Update items to exclude the deleted item
console.log(deletedItem); // Log the deleted item
console.log(items); // Log the remaining items

// modify item with id "uuid-3"
const modifieId = "uuid-3";
const updatedItem = { ...items[modifieId], title: "New item 3" };
items = { ...items, [modifieId]: updatedItem };
console.log(items);

// add new item
const newItem = { id: "uuid-4", title: "Item 4" };
items = { ...items, [newItem.id]: newItem };
console.log(items);



// if items is immutable

// Original items object
const items = {
  "uuid-1": { id: "uuid-1", title: "Item 1" },
  "uuid-2": { id: "uuid-2", title: "Item 2" },
  "uuid-3": { id: "uuid-3", title: "Item 3" },
};

// Immutable delete
const deleteId = "uuid-2";
const { [deleteId]: deletedItem, ...itemsAfterDelete } = items;

// Immutable modify
const modifyId = "uuid-3";
const itemsAfterModify = {
  ...itemsAfterDelete,
  [modifyId]: { ...itemsAfterDelete[modifyId], title: "New item 3" },
};

// Immutable add
const newItem = { id: "uuid-4", title: "Item 4" };
const itemsAfterAdd = { ...itemsAfterModify, [newItem.id]: newItem };

console.log(items); // Original items object remains unchanged
console.log(itemsAfterDelete); // Items after deletion
console.log(itemsAfterModify); // Items after modification
console.log(itemsAfterAdd); // Items after adding a new item

Function Style, Method Style

 The main difference between the function style and the use of the `filter()` method lies in the programming paradigm they represent.


1. **Function Style**: The function style represents the procedural programming paradigm. In this style, you write a sequence of commands for the computer to perform. The function `filterArray` is an example of this. It uses a `for` loop to iterate over the array and an `if` statement to check each element against the test function. This style gives you more control over the details of how the array is processed.

function filterArray(array, test) {
  let result = [];
  for (let i = 0; i < array.length; i++) {
    if (test(array[i])) {
      result.push(array[i]);
    }
  }
  return result;
}

let isEven = (num) => num % 2 === 0;
let evenNumbers = filterArray(array, isEven);

console.log('Even numbers:', evenNumbers);

2. **Method Style**: The method style represents the functional programming paradigm. In this style, you use built-in array methods like `filter()` to process the array. The `filter()` method abstracts away the details of how the array is processed, allowing you to focus on what you want to do (filter the array) rather than how to do it. This style can lead to more concise and readable code.

let evenNumbers = array.filter(num => num % 2 === 0);
console.log('Even numbers:', evenNumbers);

In general, the method style is considered more "modern" and is often preferred in JavaScript, but both styles have their uses and can be appropriate in different situations.

Avancé ! map, reduce

 const languageSkills = [

  {
    language: "Spanish",
    skill: "Professional Proficiency",
  },
  {
    language: "English",
    skill: "Professional Working Proficiency",
  },
  {
    language: "German",
    skill: "Professional Proficiency",
  },
];
const output = languageSkills.reduce((map, { language, skill }) => {
  if (map.has(skill)) map.get(skill).push(language);
  else map.set(skill, [language]);
  return map;
}, new Map());

console.log(...output);

Algo : comparaisons

 let tab = [1, 2, 3, -1, 6, 6, 1, 2, 2, 1];

let i = 0;
while (i < tab.length) {
  let j = i + 1;
  while (j < tab.length) {
    if (tab[i] === tab[j]) {
      // Swap elements
      [tab[i + 1], tab[j]] = [tab[j], tab[i + 1]];
      i++;
    }
    j++;
  }
  i++;
}

[ 1, 1, 1, -1, 6, 6, 2, 2, 2, 3 ]

let groups = tab.reduce((acc, num) => {
  acc[num] = acc[num] || [];
  acc[num].push(num);
  return acc;
}, {});

let result = [].concat(...Object.values(groups));

console.log(result);

┌─────────┬────────┐ │ (index) │ Values │ ├─────────┼────────┤ │ 0 │ 1 │ │ 1 │ 1 │ │ 2 │ 1 │ │ 3 │ 2 │ │ 4 │ 2 │ │ 5 │ 2 │ │ 6 │ 3 │ │ 7 │ 6 │ │ 8 │ 6 │ │ 9 │ -1 │ └─────────┴────────┘

map

  1. const courses = [

  2.     { name: "HTML", levels: ["L1", "L2"] },

  3.     { name: "CSS", levels: ["L1", "L2"] },

  4.     { name: "JS", levels: ["L2", "L3", "M1"] }

  5. ]


  6. const levels = new Set(courses.reduce((acc, { levels: levels }) => ([...acc, ...levels]), []));


  7. const programme = courses.reduce((a, { levels: levels, name }) => {

  8.     for (let level of levels) {

  9.         if (!a[level]) a[level] = [];

  10.         a[level].push(name);

  11.     }

  12.     return a;

  13. }, {});



  14. const menu = Object.entries(programme).map(([level, courses]) => {

  15.     return {

  16.         title: level,

  17.         subnav: courses.map((course) => {

  18.             return { title: course }

  19.         })

  20.     }

  21. })


  22. console.dir(JSON.stringify(menu));


Affiche.
[
{"title":"L1","subnav":[{"title":"HTML"},{"title":"CSS"}]}
,{"title":"L2","subnav":[{"title":"HTML"},{"title":"CSS"},{"title":"JS"}]}
,{"title":"L3","subnav":[{"title":"JS"}]}
,{"title":"M1","subnav":[{"title":"JS"}]}
]

this = un paramétre !

This doit être vu comme un paramétre.

This permet d'économiser du code en mémoire.

Exemple de code

  1. let user = { name: "John", f: say };
  2. let admin = { name: "Admin", f: say };

  3. function say(what="Hi") {
  4.   console.log(`${what} ${this.name}`);
  5. }

  6. // these calls have different this
  7. // "this" inside the function is the object "before the dot"
  8. user.f("Hello"); // John  (this == user)
  9. admin.f("Please"); // Admin  (this == admin)

  10. admin['f']();
Pour connaitre la valeur du paramétre this. Il faut regarder l'objet qui appelle la fonction !



Erreur classique.

Il est important de comprendre que this n'est pas lié à user lors de la définition




Comme un paramétre classique, c'est lors de l'appel de la méthode que l'on connait la valeur de this.


Autre exemple :


like aggregation

Voici à quoi ressemble l'aggregation dans une base de données !


const products = [

  {
    "_id": 1,
    "item": "abc",
    "price": 10,
    "quantity": 2,
    "date": "2014-03-01T08:00:00.000Z"
  },
  {
    "_id": 2,
    "item": "jkl",
    "price": 20,
    "quantity": 1,
    "date": "2014-03-01T09:00:00.000Z"
  },
  {
    "_id": 3,
    "item": "xyz",
    "price": 5,
    "quantity": 10,
    "date": "2014-03-15T09:00:00.000Z"
  },
  {
    "_id": 4,
    "item": "xyz",
    "price": 5,
    "quantity": 20,
    "date": "2014-04-04T11:21:39.736Z"
  },
  {
    "_id": 5,
    "item": "abc",
    "price": 10,
    "quantity": 10,
    "date": "2014-04-04T21:23:13.331Z"
  },
  {
    "_id": 6,
    "item": "def",
    "price": 7.5,
    "quantity": 5,
    "date": "2015-06-04T05:08:13.000Z"
  },
  {
    "_id": 7,
    "item": "def",
    "price": 7.5,
    "quantity": 10,
    "date": "2015-09-10T08:43:00.000Z"
  },
  {
    "_id": 8,
    "item": "abc",
    "price": 10,
    "quantity": 5,
    "date": "2016-02-06T20:20:13.000Z"
  }
]

 const groupBy = (arr, key) =>

arr.reduce((acc, i) => {
  (acc[i[key]] = acc[i[key]] || [] ).push(i);
  return acc;
}, {});


let result = [];
let items = groupBy(products,"item");
for (const [key, value] of Object.entries(items)) {
  // console.log(`${key}, ${value}`);
  result.push(
    {
      "_id": key,
      "totalSaleAmount": value.reduce(function(acc, cur)  {
        acc+=cur.price*cur.quantity;
        return acc
      },0)
    }
  )
}
//console.table(result)
console.log(result)

Optional Chaining ?.

 


const cours = {
    titre : "JS",
    print(){
        console.log(this.titre)
    }
}

//cours.printAll() // Error
cours.printAll?.() //Optional Chaining
cours.print()

destructuration + reduce

const dir = films.reduce( (acc, cur) => {

  acc[cur.director] = [ ... (acc[cur.director] || [] ), cur.title ];

  return acc;

}, {}); 

Remplace with regExp


html"<div> <h1> {{question}} </h1> 
<ul>
    <li>{{choice1}}</li>
    <li>{{choice2}}</li>
    <li>{{choice3}}</li>
    <li>{{choice4}}</li>
</ul>     
</div>"
randomChoise
 2
newCode"<div> <h1> {{question}} </h1> 
<ul>
    <li>{{choice1}}</li>
    <li class='selected'>{{choice2}}</li>
    <li>{{choice3}}</li>
    <li>{{choice4}}</li>
</ul>     
</div>"

Jest test

  https://github.com/dupontdenis/Jest-test1.git


test("Cat Boisson should has 2 articles", ()=> {
    expect(nbArtByCat.Boisson).toBe(2);
})

test("nb of Cats should be 5", ()=>{
    expect(Object.entries(nbArtByCat).length).toBe(5);
})

localstorage

 localStorage.setItem("saveTab",[1,2,3])

console.log(localStorage.getItem("saveTab")
> 1,2,3

Il faut utiliser JSON

localStorage.setItem("saveTAB",JSON.stringify([1,2,3]))


console.log(localStorage.getItem("saveTAB"))
> [1,2,3] // ce n'est pas un tableau mais un string

typeof localStorage.getItem("saveTAB")

> 'string'

Il faut utiliser JSON.parse
console.log(JSON.parse(localStorage.getItem("saveTAB")))
VM1856:1 (3) [1, 2, 3]
0: 1
1: 2
2: 3
length: 3[[Prototype]]: Array(0)

typeof JSON.parse(localStorage.getItem("saveTAB"))

'object'


En action

RegExp

 RegExp: \d(?=(\d{3})+\.)

Un nombre suivi de 3 nombres (une ou plusieurs fois) et un point sans les consommer (?= ).

Remplacement: $& 

Correspond au chiffre \d qui correspond.

Match 10-11
Group 14-7332
Match 23-45
Group 14-7332


https://regex101.com/r/wwpOnj/1