Pages

bind en action

class GameLoop {
  constructor(options) {
    this.options = options;
    this.running = false;
    this.raf = null;
    this.delta = 1000;
    this.accumulator = 0;
    this.last = performance.now();
  }

  start() {
    if (!this.running) {
      this.running = true;
      this.raf = window.requestAnimationFrame(this.tick.bind(this));
      console.log(this.raf);
    }
  }
  stop() {
    this.running = false;
    window.cancelAnimationFrame(this.raf);
   
  }
  tick() {
    let now = performance.now();
    let dt = now - this.last;
    this.last = now;

    this.accumulator += dt;


    while (this.accumulator >= this.delta) {
      if (this.options.render) {
        this.options.render();
      }

      this.accumulator -= this.delta;
    }

    if (true && this.options.update) {
      this.options.update(this.accumulator);
    }

    if (this.running) {
      this.raf = requestAnimationFrame(this.tick.bind(this));
    }
  }
}

let render = function() {
  const posts = [];
  const random = (min, max) => Math.floor(Math.random() * (max - min)) + min
  for (let i = 0; i < 1000; i++) {
    posts.push({
      id: `ID_${i}`,
      upVotes: random(1, 1000)
    });
  }


  console.time("sort after");
  let [c, d] = posts
    .reduce((acc, cur) => [cur, ...acc], [])
    .sort((a, b) => b.upVotes - a.upVotes)
    .slice(0, 2);
  console.timeEnd("sort after");

}
update = (v) => console.log(v);

options = {
  render,
}

let g = new GameLoop(options);
g.start();
window.setTimeout(g.stop,5000);

Impossible d’arrêter la boucle du jeu ?
trouver la faille !


lodash

  1. function baseProperty(key) {    
  2.     return function (object) {        
  3.         return object == null ? undefined : object[key];    
  4.     };
  5. }
  6. let length = baseProperty('length');
  7. console.log(length("denis"));
code

La closure

En lançant le deboggeur dans VS. on découvre la mise en place d'une closure.



Return function en action !

  1. function baseProperty(key) {    
  2.     return function (object) {        
  3.         return object == null ? undefined : object[key];    
  4.     };
  5. }
  6. let length = baseProperty('length');
  7. console.log(length("denis"));
code

La closure

En lançant le deboggeur dans VS. on découvre la mise en place d'une closure.



MAX, MIN

const data = [];

const random = (min, max) => Math.floor(Math.random() * (max - min)) + min;

for (let i = 0; i < 10000; i++) {
    data.push({ x: random(11000000) });
}

console.time("sort");   
const sortData = data.sort( (a,b) => b.x - a.x);
console.timeEnd("sort");
console.log(sortData.filter(i => i.x === sortData[0].x));

console.time("map");    
const mapData = data.map(i => i.x);
const maxData = Math.max(...mapData);
console.timeEnd("map");

console.log(mapData.filter(i => i === maxData));

$ node comparaisonsSortMinMax.js sort: 26.683ms [ { x: 999953 } ] map: 2.196ms [ 999953 ] $ node comparaisonsSortMinMax.js sort: 30.439ms [ { x: 999958 } ] map: 2.159ms [ 999958 ]

Map en action


  1. function alphabetRange (start, end, step = 1) {
  2.   return new Array(Math.ceil((end.charCodeAt(0) - start.charCodeAt(0))/step))
  3.   .fill(start.charCodeAt(0))
  4.   .map((x, i) => String.fromCharCode(i*step + start.charCodeAt(0)));
  5. }

  6. console.log(alphabetRange('c', 'h', 2));

String in action


  1. let s = 'abcdefghijklmnopqrstuvwxyz'

  2. s= s.substring(s.indexOf('p'), s.indexOf('t')+ 1);
  3. let  A= s.split('');  




code

Unique !

Nous allons donner un ensemble de fonction recherchant les valeurs uniques d'un tableau.

  1. let t = [2,0,2,0,2,3];

  2. console.time("time");
  3. unique(t);
  4. console.timeEnd("time");

Nous pourrons comparer le temps d'exécution des différentes propositions de code.

Nous pourrions également integrer un test élémentaire sur le tableau en argument
  1.   if (!Array.isArray(arr)) {
  2.     throw new TypeError('array-unique expects an array.');
  3.   }
Les écritures suivantes ne sont pas commentées
  1. function unique(t){
  2.   let cur = t.length;
  3.   while (--cur){

  4.   for (let i=0; i< cur; i++){
  5.       if (t[i] == t[cur]){
  6.           t.splice(cur,1);
  7.           break;
  8.       }
  9.   }
  10.   }
  11. }
code
  1. function unique(arr) {
  2.   let i = -1;
  3.   while (i++ < arr.length) {
  4.     var j = i + 1;

  5.     for (; j < arr.length; ++j) {
  6.       if (arr[i] === arr[j]) {
  7.         arr.splice(j--, 1);
  8.       }
  9.     }
  10.   }
  11.   return arr;
  12. };
code
  1. function unique(array) {
  2.   let passed = [];
  3.   for (let i=0 ; i < array.length; i++) {
  4.     if (array.indexOf( array[i]) === i)
  5.       passed.push(array[i]);
  6.   }
  7.   return passed;
  8. }
code
  1. function unique(t){
  2.   
  3.   let u = t.reduce(function(a,c){
  4.     if (!a.includes(c)){
  5.       a.push(c)
  6.     }
  7.     return a;   
  8.     },[])
  9.   return u;
  10. }
code
code
  1. function unique(value,index,tab){
  2.   return tab.indexOf(value) === index;
  3. }

  4. console.time("while")
  5. t = t.filter(unique);
  6. console.timeEnd("while");
  1. console.time("while")
  2. let v = [...new Set(t)];
  3. console.timeEnd("while");
  1. const T = [
  2.     { name: 'dupont', id:22 },
  3.     { name: 'dupont', id:20 },
  4.     { name: 'dupond', id:21 },
  5.     { name: 'dupond', id:21 },
  6.   ];
  7. const unique = [];
  8. const map = new Map();
  9. for (const item of T) {
  10.     if(!map.has(item.id)){
  11.         map.set(item.id, true);    // set any value to Map
  12.         unique.push({
  13.             id: item.id,
  14.             name: item.name
  15.         });
  16.     }
  17. }
  18. console.log(unique)

Projet

Ecrire l'équivalent Js de ce code Python


  1. import random
  2. from collections import Counter

  3. l = [random.randint(0,9) for i in range(10)]

  4. print (l)

  5. print(Counter(l).most_common())

  6. print(Counter(l).most_common(1))


Exemple de résultat
[6, 6, 0, 4, 8, 7, 6, 4, 7, 5]
[(6, 3), (4, 2), (7, 2), (0, 1), (8, 1), (5, 1)]
[(6, 3)]

code


deepCopy

function deepCopy(p, c={}){
  
  for (let i in p){
    if (p.hasOwnProperty(i)){
      if (typeof p[i] ==="object"){
        c[i] = Array.isArray(p[i]) ? [] : {};
        deepCopy(p[i], c[i]);
      }
      else {
        c[i] = p[i];
      }
    }
  }
  return c;

}

let u = [1,[1,2],3];

let c = deepCopy(u);

console.log(u);


code

Range : bad idea


Définition de la fonction range. lecture


passage des paramètres

Ecrire les valeurs affichées



const testPassagePara = function(args) {

    let start = args;
    
    return [start];

}

console.log(testPassagePara(1))

//-------------------------------------------
const testPassagePara = function(args) {

    let start = args;
    
    return [start];

}
console.log(testPassagePara())

//-------------------------------------------
const testPassagePara = function(args=-1) {

    let start = args;
    
    return [start];

}

console.log(testPassagePara())

//-------------------------------------------
const testPassagePara = function(...args) {

    let [start,end,step] = args;
    
    return [start,end,step];

}
console.log(testPassagePara(1, 5, 2, -1))

//-------------------------------------------
const testPassagePara = function(...args) {

    let [start,end,step] = args;

    return {start,end,step};
}


console.log(testPassagePara(1, 5, 2, -1))

//-------------------------------------------
const testPassagePara = function(...args) {

    let [start,end,step] = args;

    return {start,end,step};
}


console.log(testPassagePara(1))

//-------------------------------------------
const testPassagePara = function(...args) {

    let [start=0,end=0,step=1] = args;

    return [start,end,step];
}


console.log(testPassagePara(1))

nb occurence

const words = [1,2,7];

const alphabetical = words.reduce((a, x) => {
   if (!a[x]) a[x] = 0;
   a[x]=a[x]+1;
return a},{});

-----------------------

const alphabetical = words.reduce((a, x) => {
   if (!a[x]) a[x] = 0;
   a[x]=a[x]+1;
return a},[]);

-----------------------


const words = [1,2,2,1,5];

let min = words.reduce((a, x) => Math.min(a,x));

console.log(min);

let max = words.reduce((a, x) => Math.max(a,x));

console.log(max);

let t = Array.from({length:max-min+1},()=>0);

console.log(t);

const alphabetical = words.reduce((a, x) => {
   a[x-1]= a[x-1]+1;
return a},t);

--------------------------------


const words = [1,2,2,1,5];

let minMaxDistSumMoyNb = words.reduce((a, x) => {
   let [m,M] = [Math.min(a[0],x),Math.max(a[1],x)];
   let sum = a[3]+x;
   let nb = a[5]+1;
   let moy = sum/nb;
   return [m,M,M-m+1,sum,moy,nb]
}
,[Number.MAX_VALUE,Number.MIN_VALUE,Number.MIN_VALUE,0,0,0]);

console.log(minMaxDistSumMoyNb);

Trier en multicritère


Code

swap

en C

void swap(int *xp, int *yp)
{
    int temp = *xp;
    *xp = *yp;
    *yp = temp;
}

int main()
{
    int x=1, y=2;

    swap(&x, &y);
    printf("x = %d, y = %d", x, y);
    return 0;
}

➥ code dans Pythontutor

js


let swap = (x,y) => [y,x];

let x=1, y=2;
[x,y] = swap(x,y);
console.log(`x=${x} y=${y}`)

➥ code dans Pythontutor

Les pointeurs et les tableaux !

Aide TD max col

let TAB_MAX_Value = TAB.reduce((max_val,lig_val)=> Math.max(max_val,Math.max(...(lig_val))),Number.MIN_VALUE);



// ecriture => let TAB_Min = TAB.reduce((m,l) => Math.min(m,Math.min(...(l))),TAB[0][0]);


code source

Discussion autour des boucles

Amélioration du code

La structuration de valeurs dans un tableau, nécessite une boucle pour réaliser un parcours des valeurs.

Exemple : 

Affichons simplement les éléments d'un tableau :

let array = [1, 2, 3];
for (let i = 0; i < array.length; i++) {
  let current = array[i];
  console.log(current); // affichage
}


Imaginons l'affichage des valeurs comme une action.

for (let i = 0; i < array.length; i++) {
  let current = array[i];
  actionAffichage(current); // affichage
}


Affichage positif

Pour afficher les valeurs positives, il est facile de créer une condition ; la fonction précédente devient.

for (let i = 0; i < array.length; i++) {
  let current = array[i];
  if (current>0) actionAffichage(current);
}

ou

for (let i = 0; i < array.length; i++) {
  let current = array[i];
  actionAffichagePositif(current);
}


Affichage Négatif

Pour afficher les valeurs négatives, il est facile de créer une condition ; la fonction précédente devient.

for (let i = 0; i < array.length; i++) {
  let current = array[i];
  actionAffichageNégatif(current);
}


Bilans

Pour chaque type d'affichage, il est nécessaire de redéfinir la boucle.

Améliorations

Nous allons encapsuler le code de la boucle dans une fonction forEach.

Il nous reste à réfléchir sur le passage des actions (positif, négatif ...) comme paramètres.

Ainsi,  "afficher quelque chose" peut être vu comme une fonction.
Les fonctions étant des variables et comme les variables peuvent être passées en paramètres, on peut passer "afficher quelque chose" à une fonction.

Ainsi, la fonction "afficher quelque chose" sera passée en paramètre à la fonction forEach.

Résumé des codes


Affichage

function affVal(v){
   console.log(`val tab : ${v}`)
}


Affichage Positif

function AffPositif(v){
   if (v>0) console.log(` val positif : ${v} `);
}


Boucle sur le tableau

function forEach(array, fx) {
  for (var i = 0; i < array.length; i++)//for of
    fx(array[i]);
}


Appel


forEach(T, AffPositif);

Appel anonyme

forEach(T, function (v){
  console.log(`-> tab : ${v}`);
});


En Action

Fichier code

JS Bin on jsbin.com

Pour aller plus loin !

forEach(filtre(T, EstPositif),affVal)

Définir la fonction "filtre" qui prend en paramètre également une fonction permettant de ne concerner que certaines valeurs du tableau.

Ainsi la fonction affVal ne fait plus qu'afficher, elle ne filtre pas les valeurs. 


Série d'articles

Les pointeurs

Série d'articles sur :

    New ES6


    Les fonctions fléchées

    Cas du dom

    python tutor


    const names =  [{name:'Farrin'}, {name:'Kagure'}, {name:'Asser'}];
    const upperizedNames = names.map(function(pers) {
      return pers.toUpperCase();
    }); 

    lien

    callback bis

    Etudier le code précédent : https://jsfiddle.net/dupont/Lgre6msz/2/

    On peut changer le code avec

    class BD{


    /**
    * Finds items based on a query given as a JS object
    *
    * @param {function} function The function to filtre the query
    * @param {function} callback   The callback to fire when the query has
    * completed running
    **/
        find ( fxFilter, callback) {

            callback(this.villes.filter( fxFilter))
         }
     

    Callback

    class BD{

        constructor(villes){
            this.villes = villes;
        }
       

    /**
    * Finds items based on a query given as a JS object
    *
    * @param {object} query The query to match against (i.e. {ville: 'paris'})
    * @param {function} callback   The callback to fire when the query has
    * completed running
    **/
        find (query, callback) {

            callback(this.villes.filter(function(ville) {       
              for (let key in query) {
                if (query[key] !== ville[key]) {
                  return false
                }
              }
              return true
            }))
          }
      }

    // création d'une base
      bd = new BD([{ville:"vincennes",h:2},{ville:"paris",h:2},{ville:"roubais",h:1}]);

    document.body.insertAdjacentHTML("beforeend",`<session>${JSON.stringify(bd.villes)}</session><p> 1`)


      bd.find({h:2},function(villes){
          for(let ville of villes){
            ville["h"]=30;
          }
      });
    document.body.insertAdjacentHTML("beforeend",`<session>${JSON.stringify(bd.villes)}</session><p> 2`)

      bd.find({ville:"paris"},function(villes){
        for(let ville of villes){
           ville["capitale"]=true;
        }
    });

    document.body.insertAdjacentHTML("beforeend",`<session>${JSON.stringify(bd.villes)}</session><p>`)
     


    https://jsfiddle.net/dupont/Lgre6msz/2/

    findof versus filter

    https://jsfiddle.net/dupont/s81evw7q/5/

    Map en action

    let p = '<h1>escapeForHTML<h1>';



    let regex = /[<>&]/gi;



    let r = new Map([
      ['>','&gt;'],

      ['&','&amp;'],

      ['<', '&lt;'],

    ]);


    let f = c => r.get(c)


    document.body.insertAdjacentHTML("afterbegin",p);

    document.body.insertAdjacentHTML("afterbegin",p.replace(regex,f));