logo

 

Road to ES2023 : Chercher un élément dans un tableau en partant de la fin

Adikts - Road to ES2023

Road to ES2023 : Chercher un élément dans un tableau en partant de la fin

Chaque année, une nouvelle version de la spécification ECMAScript, derrière le langage Javascript, sort, avec son lot de fonctionnalités. Sa dernière version en date est ES 2022, sortie officiellement il y a quelques mois, sur laquelle nous vous avions proposé un article, pour présenter ses nouveautés. Après le gel des fonctionnalités incluses dans une version d’ECMAScript, les propositions d’ajouts à la spécification sont, tout au long de l’année, ajoutées à la liste des propositions qui intégreront la prochaine version d’ECMAScript. Suivre l’actualité de ces nouvelles fonctionnalités étant primordial, notamment car elles sont souvent déjà parfaitement supportées par les différents navigateurs, Node.js ainsi que Babel, nous vous proposons une nouvelle série d’articles intitulée « Road to ES2023 », reprenant tout au long de l’année les futures fonctionnalités d’ES2023, au fil de leur intégration dans la spécification, sous la forme d’un article par proposition, en commençant par la première fonctionnalité : Array.prototype.findLast et Array.prototype.findLastIndex.

Disclaimer : Dans la mesure où la spécification ES2023 n’est ni officielle ni-même gelée, il n’est pas impossible que cette fonctionnalité ne fasse finalement pas partie de cette version d’ECMAScript, par exemple dans le cas où un problème serait identifié tardivement. C’est très improbable, en particulier dans le cas des petites propositions, mais tant que la spécification n’est pas officielle, des changements peuvent arriver.

Contexte

En Javascript, depuis ES2015, il existe deux fonctions sur les tableaux, permettant de trouver le premier élément qui satisfait un prédicat, ou son index : Array.prototype.find et Array.prototype.findIndex. Ces deux fonctions offrent une approche fonctionnelle à une problématique qui aurait, auparavant, nécessité le recours à une traditionnelle boucle for pour itérer successivement sur chaque élément. Cela permet également une bien meilleure lisibilité. Cependant, ces deux fonctions ont un angle mort, elles ne permettent pas de chercher un élément dans un tableau en partant de la fin. Certes, il existe plusieurs workarounds en fonction des cas d’utilisation, mais ils sont souvent peu lisibles, peu performants, et peuvent être limités en fonction des cas. Ceux-ci pouvaient ressembler à ça :

const companies = [
  {
    name: 'Adikts',
    id: 1,
  },
  {
    name: 'Microsoft',
    id: 2,
  },
  {
    name: 'Amazon',
    id: 3,
  },
  {
    name: 'Adikts',
    id: 4,
  },
  {
    name: 'Google',
    id: 5,
  },
]

// Array.prototype.find
[...companies].reverse().find((company) => company.name === 'Adikts') // { name: 'Adikts', id: 4 }

// Array.prototype.findIndex
companies.length - 1 - [...companies].reverse().findIndex((company) => company.name === 'Adikts') // 3

Ça fonctionne, mais c’est assez opaque, très peu performant (on copie le tableau pour l’inverser et enfin itérer dessus), et cela ne couvre pas tous les cas, puisque dans le cas où findIndex renvoie -1, notre ligne renverra 5, nécessitant d’adapter notre algorithme en conséquence avec un retour peu intuitif.

C’est pour palier à ce problème qu’ES2023 intègre une proposition visant à ajouter deux nouvelles fonctions au prototype d’Array : findLast et findLastIndex, permettant enfin de chercher un élément dans un tableau en partant de la fin

Utilisation

Array.prototype.findLast et Array.prototype.findLastIndex fonctionnent de la même manière que, respectivement, Array.prototype.find et Array.prototype.findIndex, en cherchant parcourant le tableau à partir du dernier élément, pour finir par le premier. Chacune de ces fonctions prend, comme premier paramètre, une fonction, à qui sont passés respectivement l’élément sur lequel on itère son index puis le tableau en lui-même. Cette fonction doit renvoyer un booléen, et si son résultat est vrai, l’appel à Array.prototype.findLast (ou Array.prototype.findLastIndex) se termine, et la fonction renvoie le premier élément qui satisfait le prédicat, en partant de la fin (ou alors son index).

Si aucun élément dans le tableau ne correspond à la recherche, Array.prototype.findLast renverra null, alors que Array.prototype.findLastIndex renverra -1, ce qui ne change pas par rapport au comportement des fonctions d’origine. En outre, ces fonctions acceptent un second paramètre facultatif, qui sera le this de la fonction passée en paramètre, ce qui peut éviter d’avoir à recourir au bind ou aux fonctions fléchées, en offrant également de meilleures performances, de la même manière que pour de nombreuses fonctions natives de Javascript, y compris, encore une fois, les deux fonctions de base.

Ainsi, l’exemple du dessus peut maintenant s’écrire, bien plus simplement, de cette manière, nous évitant également de recourir à une copie du tableau, qui peut être coûteuse (par exemple dans le cas d’une fonction de rendu d’un composant React) :

const companies = [
  {
    name: 'Adikts',
    id: 1,
  },
  {
    name: 'Microsoft',
    id: 2,
  },
  {
    name: 'Amazon',
    id: 3,
  },
  {
    name: 'Adikts',
    id: 4,
  },
  {
    name: 'Google',
    id: 5,
  },
]

// Array.prototype.findLast
companies.findLast((company) => company.name === 'Adikts') // { name: 'Adikts', id: 4 }

// Array.prototype.findLastIndex
companies.findLastIndex((company) => company.name === 'Adikts') // 3
companies.findLastIndex((company) => company.name === 'Oracle') // -1

Compatibilité

Comme souvent en Javascript, les propositions en stade avancé sont prises en charge par les différents environnements bien avant l’officialisation de l’arrivée dans la spécification ECMAScript. Ainsi, vous pouvez utiliser ces deux fonctions dès maintenant sur les navigateurs basés sur Chromium 97 et plus récent (donc Chrome 97+, Edge 97+, Safari 15.4+, Opera 15.4). Chrome et Safari, respectivement pour Android et iOS, prennent également en charge cette fonctionnalité. Sur Firefox, ces fonctions sont prises en charge depuis la version 107. Par conséquent, tous les navigateurs dits « evergreen » actuels permettent déjà l’utilisation de cette fonctionnalité. Côté node.js, c’est disponible depuis la version 18, sortie en avril, et actuelle LTS depuis octobre, et si vous avez besoin de supporter des versions antérieures, des polyfills, tels que core.js, sont, bien-entendu, disponibles, et pourront vous permettre d’utiliser ces fonctions dans un contexte bien plus ancien.

Bien-entendu, Array.prototype.findLast et Array.prototype.findLastIndex constituent la première proposition qui devrait être intégrée à la spécification ECMAScript dans son édition de 2023, mais ce ne sera pas la seule, et de nouveaux ajouts devraient être annoncés jusqu’en mars, date de gel de la prochaine version. Continuez à suivre le blog Adikts pour rester informés des derniers ajouts à la spécification.