<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pedro Santos</title>
    <description>The latest articles on DEV Community by Pedro Santos (@pedrosantos3010).</description>
    <link>https://dev.to/pedrosantos3010</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F930209%2Fe957e400-3234-4b89-9ca3-d623018112c5.jpeg</url>
      <title>DEV Community: Pedro Santos</title>
      <link>https://dev.to/pedrosantos3010</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pedrosantos3010"/>
    <language>en</language>
    <item>
      <title>Builder de tipagem dinâmica com fluent api no typescript</title>
      <dc:creator>Pedro Santos</dc:creator>
      <pubDate>Sat, 29 Jun 2024 15:35:37 +0000</pubDate>
      <link>https://dev.to/pedrosantos3010/builder-de-tipagem-dinamica-com-fluent-api-no-typescript-3dml</link>
      <guid>https://dev.to/pedrosantos3010/builder-de-tipagem-dinamica-com-fluent-api-no-typescript-3dml</guid>
      <description>&lt;p&gt;Nesse pequeno post iremos ver uma feature interessante do typescript que não vejo muitas pessoas comentando. Iremos aprender a utilizar a criação de uma tipagem dinâmica com o padrão de fluent api. &lt;/p&gt;

&lt;p&gt;Começaremos rapidamente definindo alguns componentes para trabalhar em cima deles. A ideia aqui é construirmos casas dinamicamente. Existem casa que possuem piscina, outras não. Iremos ver como definir sua casa de acordo com o objeto que está sendo construído!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16ceys5ifd1idwh7soak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16ceys5ifd1idwh7soak.png" alt="Image description" width="541" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Começando com a fluent api, caso não esteja familiarizado com o padrão, trata-se de retornar a classe no retorno da função, para que seja possível encadear chamadas de funções. Abaixo um exemplo de utilização similar ao que faremos: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzf04wefh3i2a7oa30my5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzf04wefh3i2a7oa30my5.png" alt="Image description" width="647" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que já estamos um pouco mais familiarizados com o padrão, vamos implementar de forma que a tipagem do nosso objeto seja atualizada dinamicamente. O objetivo é ter uma função &lt;code&gt;construir&lt;/code&gt; que irá retornar a casa com a tipagem correta de nossa casa. &lt;/p&gt;

&lt;p&gt;Pra começar, primeiro precisamos de criar o tipo &lt;code&gt;Casa&lt;/code&gt;, que será definido pela extensão das variáveis existentes em CasaProps. A definição ficará da seguinte forma: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwe2bsucez4pkgjp8u7n2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwe2bsucez4pkgjp8u7n2.png" alt="Image description" width="432" height="66"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caso não esteja familiarizado com a tipagem, a explicação do que fizemos é a seguinte: &lt;/p&gt;

&lt;p&gt;a &lt;code&gt;Casa&lt;/code&gt; receberá um parametro &lt;code&gt;T&lt;/code&gt;, onde &lt;code&gt;T&lt;/code&gt; será derivado das variáveis ("chaves") presentes em &lt;code&gt;CasaProps&lt;/code&gt; (&lt;code&gt;T extends keyof CasaProps&lt;/code&gt;). Então, para cada K ("chave") presente em T iremos adicioná-la a definição da casa, sendo que associaremos o valor de K ("chave") com o valor de CasaProps&lt;a href="https://dev.toesse%20%C3%A9%20o%20valor%20da%20mesma%20chave%20s%C3%B3%20que%20na%20tipagem%20CasaProps"&gt;K&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Ainda confuso? Vamos ver o que isso representa no código, para assimilar melhor a ideia! &lt;/p&gt;

&lt;p&gt;Agora, quando criamos uma &lt;code&gt;Casa&lt;/code&gt; teremos que associar a ela uma das propriedades presentes em &lt;code&gt;CasaProps&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7t745bhipny2nfmdo5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7t745bhipny2nfmdo5z.png" alt="Image description" width="800" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao associarmos uma tipagem de &lt;code&gt;Casa&amp;lt;"quartos"&amp;gt;&lt;/code&gt; a uma variável, teremos uma casa com o atributo com quartos, que o valor terá a tipagem de &lt;code&gt;Quartos&lt;/code&gt; que definimos em &lt;code&gt;CasaProps&lt;/code&gt;. A mesma coisa acontece se fizermos uma casa com piscina, seremos forçados a incluir uma piscina dentro da casa&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdswoaj68ycsu5ims8qsu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdswoaj68ycsu5ims8qsu.png" alt="Image description" width="800" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora, a virada da chave acontece se dissermos que essa casa possui quartos e banheiros, fazemos isso indicando as duas variáveis com um &lt;code&gt;|&lt;/code&gt;. &lt;code&gt;Casa&amp;lt;"quartos" | "banheiros"&amp;gt;&lt;/code&gt; irá nos dizer que a casa terá os dois atributos existindo dentro dela! Além disso, caso não haja algum dos atributos seremos notificados com um erro explicito dizendo quais são os atributos que estão faltando:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe83sah382pb4150ex6tf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe83sah382pb4150ex6tf.png" alt="Image description" width="800" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que dominamos o conceito da tipagem dinâmica, vamos avançar para o builder. Iremos criar uma classe &lt;code&gt;CasaBuilder&lt;/code&gt;, que receberá um &lt;code&gt;T&lt;/code&gt; que estende as chaves de &lt;code&gt;CasaProps&lt;/code&gt; (&lt;code&gt;CasaBuilder&amp;lt;T extends keyof CasaProps = never&amp;gt;&lt;/code&gt; - para que em um primeiro momento não exista nenhuma chave associada ao builder setamos primeiramente como never). &lt;/p&gt;

&lt;p&gt;Para a nossa fluent api, iremos ter um objeto privado &lt;code&gt;_casa&lt;/code&gt; que receberá a configuração. Para cada um dos atributos teremos uma função específica de criação, para setar cada campo. No entanto, iremos atualizar dinamicamente nossa tipagem, retornando a tipagem &lt;code&gt;T | "variavel"&lt;/code&gt; para cada variável que setarmos (exemplo: &lt;code&gt;T | "quartos"&lt;/code&gt;&amp;gt;. Fazendo isso, iremos atualizar a nossa tipagem com um novo atributo. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiiqdozj6pkg56vglhikx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiiqdozj6pkg56vglhikx.png" alt="Image description" width="715" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por fim, teremos uma função &lt;code&gt;construir()&lt;/code&gt; que retornará a nossa casa com a tipagem atual. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvy7thf80o5xgib8fpil.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvy7thf80o5xgib8fpil.png" alt="Image description" width="375" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nossa classe ficou da seguinte forma: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcxph1wwoqcso1b0cwow6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcxph1wwoqcso1b0cwow6.png" alt="Image description" width="776" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora, é possível criar de forma dinâmica nossa casa. Para criar uma casa apenas com piscina podemos facilmente criar adicionando a piscina:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6xvuggapt1evr06isus.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6xvuggapt1evr06isus.png" alt="Image description" width="800" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ou para criar com quartos, banheiros e um quintal faremos da seguinte forma: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kdll2ybortilrmjfwci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kdll2ybortilrmjfwci.png" alt="Image description" width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Além disso, ao passar o mouse em cima do objeto já sabemos exatamente o que tem dentro da casa:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjfwwwaw3rdqi1zgjfni.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjfwwwaw3rdqi1zgjfni.png" alt="Image description" width="701" height="35"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Eu utilizei uma implementação similar a esta no backend do meu trabalho atual, para criar um serviço de parâmetros dinâmico. É um excelente jeito de simplificar tipagens complexas e ter mais controle e validação do que está sendo construído de forma dinâmica em tempo desenvolvimento.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>fluentapi</category>
      <category>node</category>
    </item>
    <item>
      <title>A maneira mais rápida de remover itens duplicados de um array em js</title>
      <dc:creator>Pedro Santos</dc:creator>
      <pubDate>Wed, 02 Aug 2023 23:09:05 +0000</pubDate>
      <link>https://dev.to/pedrosantos3010/a-maneira-mais-rapida-de-remover-duplicatas-de-um-array-em-js-2bkn</link>
      <guid>https://dev.to/pedrosantos3010/a-maneira-mais-rapida-de-remover-duplicatas-de-um-array-em-js-2bkn</guid>
      <description>&lt;p&gt;Vamos supor que você tenha uma tarefa em que você precise remover itens duplicados de um array, considerando sempre o item com a data mais recente. Para simplificar, os objetos estão na estrutura &lt;code&gt;{ id: number, date: Date }&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Exemplo de array de entrada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
    { id: 3, date: '2023-01-03T00:00:00.000Z' },
    { id: 3, date: '2023-01-04T00:00:00.000Z' },
    { id: 4, date: '2023-01-02T00:00:00.000Z' },
    { id: 3, date: '2023-01-02T00:00:00.000Z' },
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O resultado esperado seria um array com ids únicos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
    { id: 3, date: '2023-01-04T00:00:00.000Z' },
    { id: 4, date: '2023-01-02T00:00:00.000Z' },
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você saberia tratar itens em larga escala com boa performance? Qual abordagem que te vem em mente para resolver o problema?&lt;/p&gt;

&lt;p&gt;Para esse artigo, vamos gerar um array de dados aleatórios no formato de cima, pra testar a performance do código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const randomInt = (limit) =&amp;gt; Math.floor(Math.random() * limit);

const array = Array.from({ length: 100000 }).map((_, idx) =&amp;gt; ({
    id: randomInt(100),
    date: new Date(2023, 0, randomInt(31), 0, 0, 0),
}));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uma abordagem comum de se pensar para resolver esse problema é criar um método que filtre os itens do array utilizando um reduce, e/ou for. Para cada item do array verificamos se já existe aquele id no array, se não existir adicionamos ele, se existir verificamos o novo item é mais recente para substituí-lo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const removeDuplicates = (array) =&amp;gt; {
  const uniqArray = [];
  for (let i = 0; i &amp;lt; array.length; i++) {
    const item = array[i];

    const index = uniqArray.findIndex((i) =&amp;gt; i.id === item.id);

    if (index === -1) {
      uniqArray .push(item);
      continue;
    }

    if (item.date &amp;gt; uniqArray[index].date) {
      uniqArray[index] = item;
    }
  }
  return uniqArray;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa abordagem resolve o problema de uma forma relativamente simples. Podemos checar o tempo de execução que essa função leva para processar o arquivo de entrada que foi inicialmente gerado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const startTime = new Date();
removeDuplicates(array);
console.log(`Took: ${new Date() - startTime}ms`)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvxq3l5skeqvslusyxac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvxq3l5skeqvslusyxac.png" alt="Tempo de execução 35ms"&gt;&lt;/a&gt;&lt;br&gt;
35 milissegundos para processar 100.000 itens em um array, não é tão demorado, e pararmos pra pensar. Pois é, mas aí que vem a pegadinha do malandro. O problema dessa abordagem é que definitivamente não é a melhor. Isso porque temos 2 loops um dentro do outro, quanto maior a quantidade de dados diferentes, mais doloroso será para a triste máquina que ousar executar esse código. &lt;/p&gt;

&lt;p&gt;Se olharmos para nossa base de dados, temos apenas 100 ids diferentes. O que significa que o segundo loop, no pior dos casos, vai fazer apenas 100 iterações. Também significa que quanto mais ids diferente existirem, maior o tempo de demora. Com 1.000 ids diferentes ele demora 170ms e com 10.000 demora 1379ms, sim, mais de um segundo. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9w80k1mhracx4q0hziua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9w80k1mhracx4q0hziua.png" alt="gráfico execução"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O crescimento do tempo de execução é exponencial. Mas como melhorar esse algoritmo então? &lt;/p&gt;

&lt;p&gt;Vamos ver o que o chatgpt acha: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fapxlb8xtazrta45rmoyo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fapxlb8xtazrta45rmoyo.png" alt="Ideia do gpt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Admito que por esse algoritmo eu não esperava, ele está ordenando o array pelo id. Dessa forma ele consegue fazer a checagem de um id por vez, sem necessidade de realizar o find e loopar entre todos os itens de um array desordenado. Sendo assim, para ilustrar, ele verificar primeiro o id 1, compara e percebe qual o mais recente e, quando vê que chegou no id 2, armazena o item de id 1 mais recente, aí começa a verificar o id 2 e assim segue até o fim. &lt;/p&gt;

&lt;p&gt;Vamos começar a usar uma ferramenta para comparar os algoritmos, a que irei utilizar aqui será o &lt;a href="https://perf.link" rel="noopener noreferrer"&gt;perf link&lt;/a&gt;. Esse site permite iniciar uma massa de dados e comparar o tempo de execução entre cada uma das abordagens. O site realiza a mesma operação várias vezes, então a quantidade inicial do array que utilizaremos será um pouco menor, apenas 10.000, ao invés dos 100.000 iniciais, para minimizar o tempo de execução. &lt;/p&gt;

&lt;p&gt;Irei comparar o caso de existirem apenas 10 ids únicos, que significa que quase toda a massa de dados consiste em itens duplicados, e com os ids variando entre 1 e 9.000, como a função gera números aleatórios pro id não dá pra garantir que apenas 1.000 estarão duplicados, mas garantimos que tem muita probabilidade de existirem muitos ids únicos.&lt;/p&gt;

&lt;p&gt;Sem mais delongas, comparemos a performance das duas abordagens:&lt;/p&gt;

&lt;p&gt;Cenário com apenas 10 ids:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0if58r61zoggmiqyuu8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0if58r61zoggmiqyuu8.png" alt="array_find_100_gpt_56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cenário com 9.000 ids: &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgtl3038rigy9e0cxq6b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgtl3038rigy9e0cxq6b.png" alt="array_find_2_gpt_100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A performance do código do GPT é pior nos cenários em que existem mais duplicidades e melhor nos cenários infinitamente superior nos cenários que existem pouca duplicidade. &lt;/p&gt;

&lt;p&gt;Mas e se existisse uma terceira forma ainda melhor? Será possível?&lt;/p&gt;

&lt;p&gt;Bom, quando criamos um objeto no javascript ele funciona como se fosse um "dicionário" de dados, trazendo referencia direta a todas as "chaves" vinculadas aos valores. Será que conseguimos tirar proveito dessa propriedade nesse caso?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const removeDuplicatesKeyMap = (array) =&amp;gt; {
  const keyMap = {};
  for (let i = 0; i &amp;lt; array.length; i++) {
    const item = array[i];
    if (!keyMap[item.id]) {
      keyMap[item.id] = item;
      continue;
    }

    if (item.date &amp;gt; keyMap[item.id].date) {
      keyMap[item.id] = item;
    }
  }
  return Object.values(keyMap)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O código acima cria um objeto indexando as chaves como os ids do array e os valores como sendo a referência ao próprio objeto. Então o array se transformaria em algo como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    3: { id: 3, date: '2023-01-04T00:00:00.000Z' },
    4: { id: 4, date: '2023-01-02T00:00:00.000Z' },
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sempre que precisarmos de um item do array podemos acessa-lo diretamente pelo seu index, como se fosse uma propriedade normal. &lt;code&gt;keyMap[3]&lt;/code&gt; retornaria o objeto &lt;code&gt;{ id: 3, date: '2023-01-04T00:00:00.000Z' }&lt;/code&gt;. Assim seria possível facilmente acessar todos os itens de acordo com o id de cada item.&lt;/p&gt;

&lt;p&gt;Ok, a teoria parece boa, vamos ver na prática:&lt;/p&gt;

&lt;p&gt;Com 10 ids diferentes:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsel7wph0huhkpf7qlbcq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsel7wph0huhkpf7qlbcq.png" alt="gpt_40_keymap_100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com 9.000 ids diferentes:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faikjkqlt567xrr9emmuh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faikjkqlt567xrr9emmuh.png" alt="gpt_88_keymap_100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💥  Booooom  💥, toma essa GPT, hoje você foi superado!!! &lt;br&gt;
(só hoje hahaha)&lt;/p&gt;

&lt;p&gt;Achei bem interessante quando descobri essa técnica, pesquisei outras abordagens para resolver esse problema, mas essa foi a melhor que consegui pensar. &lt;/p&gt;

&lt;p&gt;Essa técnica também pode ser usada para um &lt;code&gt;in memory join&lt;/code&gt;, quando necessário. &lt;/p&gt;

&lt;p&gt;Lembrando que existem muitas outras formas de melhorar a arquitetura das aplicações para que não seja necessário executar tantos itens de uma vez. Mas performance de código, na minha visão, nunca é demais! &lt;/p&gt;

&lt;p&gt;O que aconselho a levar desse artigo é sempre tentar entender e explorar formas diferentes de resolver o mesmo problema. &lt;/p&gt;

&lt;p&gt;Você conhece conhecia essa estratégia? conhece outras estratégias para resolver o mesmo problema? compartilha com a gente aí em baixo 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://perf.link/#eyJpZCI6IjJtZjBvaTNhdGdsIiwidGl0bGUiOiJHUFQgU29ydCB2cyBLZXlNYXAiLCJiZWZvcmUiOiJjb25zdCByYW5kb21JbnQgPSAobGltaXQpID0%2BIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGxpbWl0KTtcblxuY29uc3QgYmFzZUFycmF5ID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogMTAwMDAgfSk7XG5jb25zdCBhcnJheSA9IGJhc2VBcnJheS5tYXAoKF8sIGlkeCkgPT4gKHtcbiAgICBpZDogcmFuZG9tSW50KDkwMDApLFxuICAgIGRhdGU6IG5ldyBEYXRlKDIwMjMsIDAsIHJhbmRvbUludCgzMSksIDAsIDAsIDApLFxufSkpOyIsInRlc3RzIjpbeyJuYW1lIjoic29ydGVkIiwiY29kZSI6ImNvbnN0IHJlbW92ZUR1cGxpY2F0ZVdpdGhMYXRlc3REYXRlID0gKGFycikgPT4ge1xuICBjb25zdCBzb3J0ZWRBcnJheSA9IGFyci5zb3J0KChhLCBiKSA9PiB7XG4gICAgaWYgKGEuaWQgIT09IGIuaWQpIHtcbiAgICAgIHJldHVybiBhLmlkIC0gYi5pZDtcbiAgICB9XG4gICAgcmV0dXJuIGIuZGF0ZSAtIGEuZGF0ZTtcbiAgfSk7XG5cbiAgY29uc3QgdW5pcXVlQXJyYXkgPSBbXTtcbiAgbGV0IGN1cnJlbnRJZCA9IG51bGw7XG4gIGxldCBsYXRlc3RJdGVtID0gbnVsbDtcblxuICBmb3IgKGNvbnN0IGl0ZW0gb2Ygc29ydGVkQXJyYXkpIHtcbiAgICBpZiAoY3VycmVudElkICE9PSBpdGVtLmlkKSB7XG4gICAgICBpZiAobGF0ZXN0SXRlbSkge1xuICAgICAgICB1bmlxdWVBcnJheS5wdXNoKGxhdGVzdEl0ZW0pO1xuICAgICAgfVxuICAgICAgY3VycmVudElkID0gaXRlbS5pZDtcbiAgICAgIGxhdGVzdEl0ZW0gPSBpdGVtO1xuICAgIH1cbiAgfVxuXG4gIGlmIChsYXRlc3RJdGVtKSB7XG4gICAgdW5pcXVlQXJyYXkucHVzaChsYXRlc3RJdGVtKTtcbiAgfVxuXG4gIHJldHVybiB1bmlxdWVBcnJheTtcbn07XG5jb25zdCB1bmlxdWVBcnJheSA9IHJlbW92ZUR1cGxpY2F0ZVdpdGhMYXRlc3REYXRlKGFycmF5KTsiLCJydW5zIjpbNTIzLDU3MSw0NzYsNDI4LDQ3Niw1NzEsNTIzLDQ3Niw2MTksMzgwLDYxOSw1NzEsNDc2LDUyMywzMzMsMzMzLDQyOCw1MjMsNTcxLDUyMyw1NzEsNDc2LDUyMyw1MjMsNTcxLDQ3Niw2MTksNTcxLDYxOSw0NzYsNTcxLDU3MSw1MjMsNTIzLDQyOCw2MTksNTcxLDQ3Niw0NzYsNjE5LDYxOSw1NzEsNTcxLDM4MCw1NzEsNTIzLDU3MSw1NzEsNTIzLDUyMyw1NzEsNTcxLDQyOCw2MTksNTcxLDU3MSw0NzYsMzMzLDU3MSw1NzEsNTcxLDYxOSw1NzEsNTcxLDUyMyw1MjMsNTcxLDYxOSw1NzEsNTIzLDYxOSw0MjgsNTcxLDYxOSwzMzMsNTcxLDM4MCw1MjMsNTIzLDUyMyw0NzYsNTcxLDU3MSw1MjMsNjE5LDYxOSw1MjMsNTcxLDUyMyw1MjMsNjE5LDUyMyw2NjYsNTIzLDI4NSwxOTAsMjM4LDIzOCwyMzgsMzgwXSwib3BzIjo1MTZ9LHsibmFtZSI6IktleU1hcCIsImNvZGUiOiJjb25zdCBrZXlNYXAgPSB7fTtcbmZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBpdGVtID0gYXJyYXlbaV07XG4gICAgaWYgKCFrZXlNYXBbaXRlbS5pZF0pIHtcbiAgICAgICAga2V5TWFwW2l0ZW0uaWRdID0gaXRlbTtcbiAgICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGtleU1hcFtpdGVtLmlkXS5kYXRlIDwgaXRlbS5kYXRlKSB7XG4gICAgICAgIGtleU1hcFtpdGVtLmlkXSA9IGl0ZW07XG4gICAgfVxufVxuY29uc3QgdW5pcXVlQXJyYXkgPSBPYmplY3QudmFsdWVzKGtleU1hcCkiLCJydW5zIjpbNjE5LDU3MSw1NzEsNTIzLDUyMyw2MTksNTcxLDU3MSw1MjMsNDc2LDYxOSw2NjYsNTcxLDY2Niw1MjMsMzgwLDYxOSw1NzEsNjY2LDYxOSw2MTksNTcxLDY2Niw2MTksNjE5LDU3MSw2NjYsNjE5LDY2Niw1MjMsNjY2LDYxOSw1NzEsNTIzLDQ3Niw2NjYsNTIzLDYxOSw1NzEsNzE0LDY2Niw2MTksNjE5LDU3MSw2MTksNjY2LDY2Niw1NzEsNjE5LDYxOSw2NjYsNjY2LDU3MSw2MTksNjE5LDYxOSw1NzEsNDI4LDY2Niw1NzEsNjY2LDY2Niw2MTksNjE5LDYxOSw2MTksNjE5LDcxNCw2NjYsNTcxLDYxOSw2MTksNTcxLDY2Niw1NzEsNjE5LDUyMyw2MTksNjE5LDYxOSw1MjMsNTIzLDYxOSw1NzEsNjY2LDYxOSw2MTksNjE5LDYxOSw2MTksNjE5LDU3MSw3MTQsNTcxLDQyOCwzMzMsMzMzLDM4MCwzODAsNDc2XSwib3BzIjo1OTB9XSwidXBkYXRlZCI6IjIwMjMtMDgtMDJUMjM6MDk6MzEuNjI1WiJ9" rel="noopener noreferrer"&gt;aqui tem o link para acessar ao cenário gpt vs keymap&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>performance</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
