CINXE.COM

<!DOCTYPE html><html lang="en" data-theme-enabled="1"><head><script>window.currentUser = null;</script><script>window.shopCurrency = "EUR";</script><script>window.localCurrency = "EUR";</script><script>window.countryCode = "in";</script><script>window.rateShopTo = {"EUR":1,"USD":1.081276295287906,"AMD":423.6440524938016};</script><title itemprop="name">Array methods</title><link href="/pack/styles.c582d23a0695e653a6d3.css" rel="stylesheet"><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes, minimum-scale=1.0"><meta name="apple-mobile-web-app-capable" content="yes"><script>if (window.devicePixelRatio > 1) document.cookie = 'pixelRatio=' + window.devicePixelRatio + ';path=/;expires=Tue, 19 Jan 2038 03:14:07 GMT';</script><link href="//fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic" rel="stylesheet"><link rel="apple-touch-icon-precomposed" href="/img/favicon/apple-touch-icon-precomposed.png"><link rel="canonical" href="https://javascript.info/array-methods"><meta name="msapplication-TileColor" content="#222A2C"><meta name="msapplication-TileImage" content="/img/favicon/tileicon.png"><link rel="icon" href="/img/favicon/favicon.png"><meta itemprop="image" content="https://javascript.info/img/site_preview_en_512x512.png"><meta property="og:title" content="Array methods"><meta property="og:image" content="https://javascript.info/img/site_preview_en_1200x630.png"><meta property="og:image:type" content="image/png"><meta property="og:image:width" content="1200"><meta property="og:image:height" content="630"><meta property="fb:admins" content="100001562528165"><meta name="twitter:card" content="summary"><meta name="twitter:title" content="Array methods"><meta name="twitter:site" content="@iliakan"><meta name="twitter:creator" content="@iliakan"><meta name="twitter:image" content="https://javascript.info/img/site_preview_en_512x512.png"><meta name="google-adsense-account" content="ca-pub-6204518652652613"><link rel="prev" href="/array"><link rel="next" href="/iterable"><script data-collect-dnt="true" async src="https://scripts.simpleanalyticscdn.com/latest.js"></script><script>window.GA_ID = "UA-2056213-15";</script><script>window.YANDEX_METRIKA_ID = 32184394;</script><script>{function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-2LWB61WGYJ")}</script> <script async src="https://www.googletagmanager.com/gtag/js?id=G-2LWB61WGYJ"></script><script>window.metrika={reachGoal:function(){}},window.yandex_metrika_callbacks=[function(){try{window.metrika=new Ya.Metrika({id:YANDEX_METRIKA_ID,webvisor:!0,clickmap:!0,params:{user:window.currentUser&&window.currentUser.id}}),metrika.trackLinks({delay:150}),window.addEventListener("error",function(r){window.metrika.reachGoal("JSERROR",{src:(r.filename||r.errorUrl)+": "+(r.lineno||r.errorLine),stack:r.stack||r.error&&r.error.stack,message:r.message})})}catch(r){}}];</script><script src="//mc.yandex.ru/metrika/watch.js" async></script><script>window.RECAPTCHA_ID = "6LfmLAEVAAAAAJMykMnf7aY8nkyTRmYi2ynx51R1";</script><script src="/pack/init.c620e89b5f96f3cade19.js"></script><script src="/pack/head.7de24b11bdf2e7982166.js" defer></script><meta property="og:title" content="Array methods"><meta property="og:type" content="article"><script src="/pack/tutorial.aa68ac65c8ad26a37344.js" defer></script><script src="/pack/footer.818a809d6860f4026867.js" defer></script></head><body class="no-icons"><script>window.fontTest();</script><div class="page-wrapper page-wrapper_sidebar_on"><!--[if IE]><div style="color:red;text-align:center">Sorry, Internet Explorer is not supported, please use a newer browser.</div><![endif]--><div class="sitetoolbar sitetoolbar_tutorial"><script>window.langs = [{"code":"ar","name":"Arabic"},{"code":"az","name":"Azerbaijani"},{"code":"bg","name":"Bulgarian"},{"code":"bn","name":"Bengali"},{"code":"bs","name":"Bosnian"},{"code":"ca","name":"Catalan"},{"code":"cs","name":"Czech"},{"code":"da","name":"Danish"},{"code":"de","name":"German"},{"code":"el","name":"Greek"},{"code":"en","name":"English"},{"code":"es","name":"Spanish"},{"code":"fa","name":"Persian (Farsi)"},{"code":"fi","name":"Finnish"},{"code":"fr","name":"French"},{"code":"he","name":"Hebrew"},{"code":"hi","name":"Hindi"},{"code":"hr","name":"Croatian"},{"code":"hu","name":"Hungarian"},{"code":"hy","name":"Armenian"},{"code":"id","name":"Indonesian"},{"code":"it","name":"Italian"},{"code":"ja","name":"Japanese"},{"code":"ka","name":"Georgian"},{"code":"kk","name":"Kazakh"},{"code":"km","name":"Central Khmer"},{"code":"ko","name":"Korean"},{"code":"ku","name":"Kurdish"},{"code":"ky","name":"Kyrgyz"},{"code":"lt","name":"Lithuanian"},{"code":"me","name":"Montenegrin"},{"code":"ml","name":"Malayalam"},{"code":"ms","name":"Malay"},{"code":"my","name":"Burmese"},{"code":"nl","name":"Dutch"},{"code":"no","name":"Norvegian"},{"code":"pa","name":"Punjabi"},{"code":"pl","name":"Polish"},{"code":"pt","name":"Portuguese"},{"code":"ro","name":"Romanian"},{"code":"ru","name":"Russian"},{"code":"si","name":"Sinhala"},{"code":"sk","name":"Slovak"},{"code":"sl","name":"Slovenian"},{"code":"sq","name":"Albanian"},{"code":"sr","name":"Serbian"},{"code":"ta","name":"Tamil"},{"code":"te","name":"Telugu"},{"code":"test","name":"Test"},{"code":"th","name":"Thai"},{"code":"tk","name":"Turkmen"},{"code":"tr","name":"Turkish"},{"code":"ug","name":"Uyghur"},{"code":"uk","name":"Ukrainian"},{"code":"ur","name":"Urdu"},{"code":"uz","name":"Uzbek"},{"code":"v2","name":"v2"},{"code":"vi","name":"Vietnamese"},{"code":"zh-hant","name":"Chinese Traditional"},{"code":"zh","name":"Chinese"}];</script><script>window.lang = "en";</script><div class="sitetoolbar__content"><div class="sitetoolbar__lang-switcher"><button class="sitetoolbar__dropdown-button" data-dropdown-toggler>EN</button><div class="sitetoolbar__dropdown-wrap"><div class="sitetoolbar__dropdown-body"><div class="sitetoolbar__lang-switcher-body"><div class="supported-langs supported-langs_toolbar"><div class="supported-langs__container"><ul class="supported-langs__list" style="height:200px"><li class="supported-langs__item"><a class="supported-langs__link" href="https://ar.javascript.info/array-methods"><span class="supported-langs__brief">AR</span><span class="supported-langs__title">عربي</span></a></li><li class="supported-langs__item supported-langs__item_current"><a class="supported-langs__link" href="https://javascript.info/array-methods"><span class="supported-langs__brief">EN</span><span class="supported-langs__title">English</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://es.javascript.info/array-methods"><span class="supported-langs__brief">ES</span><span class="supported-langs__title">Español</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://fa.javascript.info/array-methods"><span class="supported-langs__brief">FA</span><span class="supported-langs__title">فارسی</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://fr.javascript.info/array-methods"><span class="supported-langs__brief">FR</span><span class="supported-langs__title">Français</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://id.javascript.info/array-methods"><span class="supported-langs__brief">ID</span><span class="supported-langs__title">Indonesia</span></a></li></ul><ul class="supported-langs__list" style="height:200px"><li class="supported-langs__item"><a class="supported-langs__link" href="https://it.javascript.info/array-methods"><span class="supported-langs__brief">IT</span><span class="supported-langs__title">Italiano</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://ja.javascript.info/array-methods"><span class="supported-langs__brief">JA</span><span class="supported-langs__title">日本語</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://ko.javascript.info/array-methods"><span class="supported-langs__brief">KO</span><span class="supported-langs__title">한국어</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://learn.javascript.ru/array-methods"><span class="supported-langs__brief">RU</span><span class="supported-langs__title">Русский</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://tr.javascript.info/array-methods"><span class="supported-langs__brief">TR</span><span class="supported-langs__title">Türkçe</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://uk.javascript.info/array-methods"><span class="supported-langs__brief">UK</span><span class="supported-langs__title">Українська</span></a></li></ul><ul class="supported-langs__list" style="height:20px"><li class="supported-langs__item"><a class="supported-langs__link" href="https://zh.javascript.info/array-methods"><span class="supported-langs__brief">ZH</span><span class="supported-langs__title">简体中文</span></a></li></ul></div><div class="supported-langs__text"><p>We want to make this open-source project available for people all around the world.</p> <p><a href="https://javascript.info/translate">Help to translate</a> the content of this tutorial to your language!</p> </div></div></div></div></div></div><div class="sitetoolbar__logo-wrap"><a class="sitetoolbar__link sitetoolbar__link_logo" href="/"><img class="sitetoolbar__logo sitetoolbar__logo_normal" src="/img/sitetoolbar__logo_en.svg" width="200" alt="" role="presentation"/><img class="sitetoolbar__logo sitetoolbar__logo_normal sitetoolbar__logo_dark" src="/img/sitetoolbar__logo_en-white.svg" width="200" alt="" role="presentation"/><img class="sitetoolbar__logo sitetoolbar__logo_small" src="/img/sitetoolbar__logo_small_en.svg" width="70" alt="" role="presentation"/><img class="sitetoolbar__logo sitetoolbar__logo_small sitetoolbar__logo_dark" src="/img/sitetoolbar__logo_small_en-white.svg" width="70" alt="" role="presentation"/><script>Array.prototype.forEach.call(document.querySelectorAll("img.sitetoolbar__logo"),function(e){let t=document.createElement("object");t.type="image/svg+xml",t.className=e.className,t.style.cssText="left:0;top:0;position:absolute",t.onload=function(){t.onload=null,e.style.visibility="hidden"},t.data=e.src,e.parentNode.insertBefore(t,e)});</script></a></div><div class="sitetoolbar__nav-toggle-wrap"><button class="sitetoolbar__nav-toggle" type="button"></button></div><nav class="sitetoolbar__sections"><ul class="sitetoolbar__sections-list"></ul></nav><div class="sitetoolbar__right-button-wrap"><a class="sitetoolbar-right-button sitetoolbar-right-button_courses" href="/ebook"><span class="sitetoolbar-right-button__extra-text">Buy</span>EPUB/PDF</a></div><div class="sitetoolbar__login-wrap"><button class="sitetoolbar__login sitetoolbar__login_unready" data-action-login></button></div><div class="sitetoolbar__theme-switcher"><div class="theme-changer"><label class="theme-changer__label" for="theme-changer-input" data-tooltip="Change theme"><input class="theme-changer__input" type="checkbox" id="theme-changer-input" data-theme-changer="data-theme-changer"/><span class="theme-changer__icon theme-changer__icon_light-theme"></span><span class="theme-changer__icon theme-changer__icon_dark-theme"></span></label></div></div><div class="sitetoolbar__search-wrap"><div class="sitetoolbar__search-content"><button class="sitetoolbar__search-toggle" type="button"></button><form class="sitetoolbar__search" method="GET" action="/search"><div class="sitetoolbar__search-input"><div class="text-input"><input class="text-input__control" name="query" placeholder="Search on Javascript.info" required="required" type="text"/></div><button class="sitetoolbar__find" type="submit">Search</button></div></form></div></div></div><div class="tablet-menu"><div class="tablet-menu__line"><div class="tablet-menu__content"><form class="tablet-menu-search" action="/search/"><input class="tablet-menu-search__input" type="search" name="query" placeholder="Search in the tutorial" required="required"/><button class="tablet-menu-search__button" type="submit" name="type" value="articles">Search</button></form></div></div><div class="tablet-menu__line"><div class="tablet-menu__content"><a class="map" href="/tutorial/map" data-action="tutorial-map"><span class="map__text">Tutorial map</span></a></div></div><div class="tablet-menu__line"><div class="tablet-menu__content"><div class="theme-changer theme-changer_tablet-menu theme-changer_has-label"><label class="theme-changer__label" for="theme-changer-input-tablet" data-tooltip="Change theme"><input class="theme-changer__input" type="checkbox" id="theme-changer-input-tablet" data-theme-changer="data-theme-changer"/><span class="theme-changer__icon theme-changer__icon_light-theme"></span><span class="theme-changer__icon theme-changer__icon_dark-theme"></span><span class="theme-changer__label-text theme-changer__label-text_light-theme">Light theme</span><span class="theme-changer__label-text theme-changer__label-text_dark-theme">Dark theme</span></label></div></div></div><div class="tablet-menu__line"><div class="tablet-menu__content"><div class="share-icons"><span class="share-icons__title">Share</span><a class="share share_tw" href="https://twitter.com/share?url=https%3A%2F%2Fjavascript.info%2Farray-methods" rel="nofollow"></a><a class="share share_fb" href="https://www.facebook.com/sharer/sharer.php?s=100&amp;p%5Burl%5D=https%3A%2F%2Fjavascript.info%2Farray-methods" rel="nofollow"></a></div></div></div><div class="tablet-menu__line"><div class="tablet-menu__content"><select class="tablet-menu__nav input-select input-select input-select_small" onchange="if(this.value) window.location.href=this.value"><option value="https://ar.javascript.info/array-methods">عربي</option><option value="https://javascript.info/array-methods" selected>English</option><option value="https://es.javascript.info/array-methods">Español</option><option value="https://fa.javascript.info/array-methods">فارسی</option><option value="https://fr.javascript.info/array-methods">Français</option><option value="https://id.javascript.info/array-methods">Indonesia</option><option value="https://it.javascript.info/array-methods">Italiano</option><option value="https://ja.javascript.info/array-methods">日本語</option><option value="https://ko.javascript.info/array-methods">한국어</option><option value="https://learn.javascript.ru/array-methods">Русский</option><option value="https://tr.javascript.info/array-methods">Türkçe</option><option value="https://uk.javascript.info/array-methods">Українська</option><option value="https://zh.javascript.info/array-methods">简体中文</option></select></div></div></div><progress class="tutorial-progress" data-sticky value="41" max="94" data-tooltip="Lesson 41 of 94"></progress></div><div class="page page_sidebar_on page_inner_padding"><script>if(localStorage.noSidebar){document.querySelector(".page").classList.remove("page_sidebar_on");let e=document.querySelector(".page-wrapper");e&&e.classList.remove("page-wrapper_sidebar_on")}setTimeout(function(){document.querySelector(".page").classList.add("page_sidebar-animation-on")});</script><div class="page__inner"><main class="main main_width-limit"><header class="main__header"><div class="main__header-inner"><div class="main__header-group"><ol class="breadcrumbs"><li class="breadcrumbs__item breadcrumbs__item_home"><a class="breadcrumbs__link" href="/"><span class="breadcrumbs__hidden-text">Tutorial</span></a></li><li class="breadcrumbs__item" id="breadcrumb-1"><a class="breadcrumbs__link" href="/js"><span>The JavaScript language</span></a></li><li class="breadcrumbs__item" id="breadcrumb-2"><a class="breadcrumbs__link" href="/data-types"><span>Data types</span></a></li><script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Tutorial","item":"https://javascript.info/"},{"@type":"ListItem","position":2,"name":"The JavaScript language","item":"https://javascript.info/js"},{"@type":"ListItem","position":3,"name":"Data types","item":"https://javascript.info/data-types"}]}</script></ol><div class="updated-at" data-tooltip="Last updated on December 31, 2023"><div class="updated-at__content">December 31, 2023</div></div></div><h1 class="main__header-title">Array methods</h1></div></header><div class="content"><article class="formatted" itemscope itemtype="http://schema.org/TechArticle"><meta itemprop="name" content="Array methods"><div itemprop="author" itemscope itemtype="http://schema.org/Person"><meta itemprop="email" content="iliakan@gmail.com"><meta itemprop="name" content="Ilya Kantor"></div><div itemprop="articleBody"><p>Arrays provide a lot of methods. To make things easier, in this chapter, they are split into groups.</p> <h2><a class="main__anchor" name="add-remove-items" href="#add-remove-items">Add/remove items</a></h2><p>We already know methods that add and remove items from the beginning or the end:</p> <ul> <li><code>arr.push(...items)</code> – adds items to the end,</li> <li><code>arr.pop()</code> – extracts an item from the end,</li> <li><code>arr.shift()</code> – extracts an item from the beginning,</li> <li><code>arr.unshift(...items)</code> – adds items to the beginning.</li> </ul> <p>Here are a few others.</p> <h3><a class="main__anchor" name="splice" href="#splice">splice</a></h3><p>How to delete an element from the array?</p> <p>The arrays are objects, so we can try to use <code>delete</code>:</p> <div id="81p67yyhtj" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [&quot;I&quot;, &quot;go&quot;, &quot;home&quot;]; delete arr[1]; // remove &quot;go&quot; alert( arr[1] ); // undefined // now arr = [&quot;I&quot;, , &quot;home&quot;]; alert( arr.length ); // 3</code></pre> </div> </div> </div><p>The element was removed, but the array still has 3 elements, we can see that <code>arr.length == 3</code>.</p> <p>That’s natural, because <code>delete obj.key</code> removes a value by the <code>key</code>. It’s all it does. Fine for objects. But for arrays we usually want the rest of the elements to shift and occupy the freed place. We expect to have a shorter array now.</p> <p>So, special methods should be used.</p> <p>The <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">arr.splice</a> method is a Swiss army knife for arrays. It can do everything: insert, remove and replace elements.</p> <p>The syntax is:</p> <div id="7zk0ge8iq3" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>arr.splice(start[, deleteCount, elem1, ..., elemN])</code></pre> </div> </div> </div><p>It modifies <code>arr</code> starting from the index <code>start</code>: removes <code>deleteCount</code> elements and then inserts <code>elem1, ..., elemN</code> at their place. Returns the array of removed elements.</p> <p>This method is easy to grasp by examples.</p> <p>Let’s start with the deletion:</p> <div id="xwgiyudacy" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:2,&quot;end&quot;:2}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [&quot;I&quot;, &quot;study&quot;, &quot;JavaScript&quot;]; arr.splice(1, 1); // from index 1 remove 1 element alert( arr ); // [&quot;I&quot;, &quot;JavaScript&quot;]</code></pre> </div> </div> </div><p>Easy, right? Starting from the index <code>1</code> it removed <code>1</code> element.</p> <p>In the next example, we remove 3 elements and replace them with the other two:</p> <div id="is1ngdsbeo" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:5,&quot;cols&quot;:[{&quot;start&quot;:21,&quot;end&quot;:37}]},{&quot;start&quot;:0,&quot;cols&quot;:[{&quot;start&quot;:11,&quot;end&quot;:38}]}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [&quot;I&quot;, &quot;study&quot;, &quot;JavaScript&quot;, &quot;right&quot;, &quot;now&quot;]; // remove 3 first elements and replace them with another arr.splice(0, 3, &quot;Let's&quot;, &quot;dance&quot;); alert( arr ) // now [&quot;Let's&quot;, &quot;dance&quot;, &quot;right&quot;, &quot;now&quot;]</code></pre> </div> </div> </div><p>Here we can see that <code>splice</code> returns the array of removed elements:</p> <div id="0m3i6s84yk" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:0,&quot;cols&quot;:[{&quot;start&quot;:11,&quot;end&quot;:24}]}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [&quot;I&quot;, &quot;study&quot;, &quot;JavaScript&quot;, &quot;right&quot;, &quot;now&quot;]; // remove 2 first elements let removed = arr.splice(0, 2); alert( removed ); // &quot;I&quot;, &quot;study&quot; &lt;-- array of removed elements</code></pre> </div> </div> </div><p>The <code>splice</code> method is also able to insert the elements without any removals. For that, we need to set <code>deleteCount</code> to <code>0</code>:</p> <div id="ly9ns44v6o" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [&quot;I&quot;, &quot;study&quot;, &quot;JavaScript&quot;]; // from index 2 // delete 0 // then insert &quot;complex&quot; and &quot;language&quot; arr.splice(2, 0, &quot;complex&quot;, &quot;language&quot;); alert( arr ); // &quot;I&quot;, &quot;study&quot;, &quot;complex&quot;, &quot;language&quot;, &quot;JavaScript&quot;</code></pre> </div> </div> </div><div class="important important_smart"> <div class="important__header"><span class="important__type">Negative indexes allowed</span></div> <div class="important__content"><p>Here and in other array methods, negative indexes are allowed. They specify the position from the end of the array, like here:</p> <div id="wuy98qtapc" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [1, 2, 5]; // from index -1 (one step from the end) // delete 0 elements, // then insert 3 and 4 arr.splice(-1, 0, 3, 4); alert( arr ); // 1,2,3,4,5</code></pre> </div> </div> </div></div></div> <h3><a class="main__anchor" name="slice" href="#slice">slice</a></h3><p>The method <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">arr.slice</a> is much simpler than the similar-looking <code>arr.splice</code>.</p> <p>The syntax is:</p> <div id="hyliyi4xu7" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>arr.slice([start], [end])</code></pre> </div> </div> </div><p>It returns a new array copying to it all items from index <code>start</code> to <code>end</code> (not including <code>end</code>). Both <code>start</code> and <code>end</code> can be negative, in that case position from array end is assumed.</p> <p>It’s similar to a string method <code>str.slice</code>, but instead of substrings, it makes subarrays.</p> <p>For instance:</p> <div id="wwhn3p2c8u" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [&quot;t&quot;, &quot;e&quot;, &quot;s&quot;, &quot;t&quot;]; alert( arr.slice(1, 3) ); // e,s (copy from 1 to 3) alert( arr.slice(-2) ); // s,t (copy from -2 till the end)</code></pre> </div> </div> </div><p>We can also call it without arguments: <code>arr.slice()</code> creates a copy of <code>arr</code>. That’s often used to obtain a copy for further transformations that should not affect the original array.</p> <h3><a class="main__anchor" name="concat" href="#concat">concat</a></h3><p>The method <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat">arr.concat</a> creates a new array that includes values from other arrays and additional items.</p> <p>The syntax is:</p> <div id="1c4hgwz9p6" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>arr.concat(arg1, arg2...)</code></pre> </div> </div> </div><p>It accepts any number of arguments – either arrays or values.</p> <p>The result is a new array containing items from <code>arr</code>, then <code>arg1</code>, <code>arg2</code> etc.</p> <p>If an argument <code>argN</code> is an array, then all its elements are copied. Otherwise, the argument itself is copied.</p> <p>For instance:</p> <div id="t5iucs4bip" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [1, 2]; // create an array from: arr and [3,4] alert( arr.concat([3, 4]) ); // 1,2,3,4 // create an array from: arr and [3,4] and [5,6] alert( arr.concat([3, 4], [5, 6]) ); // 1,2,3,4,5,6 // create an array from: arr and [3,4], then add values 5 and 6 alert( arr.concat([3, 4], 5, 6) ); // 1,2,3,4,5,6</code></pre> </div> </div> </div><p>Normally, it only copies elements from arrays. Other objects, even if they look like arrays, are added as a whole:</p> <div id="2v750g7t1x" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [1, 2]; let arrayLike = { 0: &quot;something&quot;, length: 1 }; alert( arr.concat(arrayLike) ); // 1,2,[object Object]</code></pre> </div> </div> </div><p>…But if an array-like object has a special <code>Symbol.isConcatSpreadable</code> property, then it’s treated as an array by <code>concat</code>: its elements are added instead:</p> <div id="9r20gzxkon" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:5,&quot;end&quot;:5}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [1, 2]; let arrayLike = { 0: &quot;something&quot;, 1: &quot;else&quot;, [Symbol.isConcatSpreadable]: true, length: 2 }; alert( arr.concat(arrayLike) ); // 1,2,something,else</code></pre> </div> </div> </div><h2><a class="main__anchor" name="iterate-foreach" href="#iterate-foreach">Iterate: forEach</a></h2><p>The <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">arr.forEach</a> method allows to run a function for every element of the array.</p> <p>The syntax:</p> <div id="4bpqh40y14" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>arr.forEach(function(item, index, array) { // ... do something with an item });</code></pre> </div> </div> </div><p>For instance, this shows each element of the array:</p> <div id="hr8e0j07r0" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>// for each element call alert [&quot;Bilbo&quot;, &quot;Gandalf&quot;, &quot;Nazgul&quot;].forEach(alert);</code></pre> </div> </div> </div><p>And this code is more elaborate about their positions in the target array:</p> <div id="n6xhlepz9c" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>[&quot;Bilbo&quot;, &quot;Gandalf&quot;, &quot;Nazgul&quot;].forEach((item, index, array) =&gt; { alert(`${item} is at index ${index} in ${array}`); });</code></pre> </div> </div> </div><p>The result of the function (if it returns any) is thrown away and ignored.</p> <h2><a class="main__anchor" name="searching-in-array" href="#searching-in-array">Searching in array</a></h2><p>Now let’s cover methods that search in an array.</p> <h3><a class="main__anchor" name="indexof-lastindexof-and-includes" href="#indexof-lastindexof-and-includes">indexOf/lastIndexOf and includes</a></h3><p>The methods <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf">arr.indexOf</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes">arr.includes</a> have the similar syntax and do essentially the same as their string counterparts, but operate on items instead of characters:</p> <ul> <li><code>arr.indexOf(item, from)</code> – looks for <code>item</code> starting from index <code>from</code>, and returns the index where it was found, otherwise <code>-1</code>.</li> <li><code>arr.includes(item, from)</code> – looks for <code>item</code> starting from index <code>from</code>, returns <code>true</code> if found.</li> </ul> <p>Usually, these methods are used with only one argument: the <code>item</code> to search. By default, the search is from the beginning.</p> <p>For instance:</p> <div id="dlzo6g8d6i" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [1, 0, false]; alert( arr.indexOf(0) ); // 1 alert( arr.indexOf(false) ); // 2 alert( arr.indexOf(null) ); // -1 alert( arr.includes(1) ); // true</code></pre> </div> </div> </div><p>Please note that <code>indexOf</code> uses the strict equality <code>===</code> for comparison. So, if we look for <code>false</code>, it finds exactly <code>false</code> and not the zero.</p> <p>If we want to check if <code>item</code> exists in the array and don’t need the index, then <code>arr.includes</code> is preferred.</p> <p>The method <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf">arr.lastIndexOf</a> is the same as <code>indexOf</code>, but looks for from right to left.</p> <div id="z3dicy5yhk" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let fruits = ['Apple', 'Orange', 'Apple'] alert( fruits.indexOf('Apple') ); // 0 (first Apple) alert( fruits.lastIndexOf('Apple') ); // 2 (last Apple)</code></pre> </div> </div> </div><div class="important important_smart"> <div class="important__header"><span class="important__type">The <code>includes</code> method handles <code>NaN</code> correctly</span></div> <div class="important__content"><p>A minor, but noteworthy feature of <code>includes</code> is that it correctly handles <code>NaN</code>, unlike <code>indexOf</code>:</p> <div id="fy0x1tr9p5" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>const arr = [NaN]; alert( arr.indexOf(NaN) ); // -1 (wrong, should be 0) alert( arr.includes(NaN) );// true (correct)</code></pre> </div> </div> </div><p>That’s because <code>includes</code> was added to JavaScript much later and uses the more up-to-date comparison algorithm internally.</p> </div></div> <h3><a class="main__anchor" name="find-and-findindex-findlastindex" href="#find-and-findindex-findlastindex">find and findIndex/findLastIndex</a></h3><p>Imagine we have an array of objects. How do we find an object with a specific condition?</p> <p>Here the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find">arr.find(fn)</a> method comes in handy.</p> <p>The syntax is:</p> <div id="1cmp6os77u" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let result = arr.find(function(item, index, array) { // if true is returned, item is returned and iteration is stopped // for falsy scenario returns undefined });</code></pre> </div> </div> </div><p>The function is called for elements of the array, one after another:</p> <ul> <li><code>item</code> is the element.</li> <li><code>index</code> is its index.</li> <li><code>array</code> is the array itself.</li> </ul> <p>If it returns <code>true</code>, the search is stopped, the <code>item</code> is returned. If nothing is found, <code>undefined</code> is returned.</p> <p>For example, we have an array of users, each with the fields <code>id</code> and <code>name</code>. Let’s find the one with <code>id == 1</code>:</p> <div id="n10u6evlps" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let users = [ {id: 1, name: &quot;John&quot;}, {id: 2, name: &quot;Pete&quot;}, {id: 3, name: &quot;Mary&quot;} ]; let user = users.find(item =&gt; item.id == 1); alert(user.name); // John</code></pre> </div> </div> </div><p>In real life, arrays of objects are a common thing, so the <code>find</code> method is very useful.</p> <p>Note that in the example we provide to <code>find</code> the function <code>item =&gt; item.id == 1</code> with one argument. That’s typical, other arguments of this function are rarely used.</p> <p>The <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex">arr.findIndex</a> method has the same syntax but returns the index where the element was found instead of the element itself. The value of <code>-1</code> is returned if nothing is found.</p> <p>The <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findLastIndex">arr.findLastIndex</a> method is like <code>findIndex</code>, but searches from right to left, similar to <code>lastIndexOf</code>.</p> <p>Here’s an example:</p> <div id="6ebvopm7aw" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let users = [ {id: 1, name: &quot;John&quot;}, {id: 2, name: &quot;Pete&quot;}, {id: 3, name: &quot;Mary&quot;}, {id: 4, name: &quot;John&quot;} ]; // Find the index of the first John alert(users.findIndex(user =&gt; user.name == 'John')); // 0 // Find the index of the last John alert(users.findLastIndex(user =&gt; user.name == 'John')); // 3</code></pre> </div> </div> </div><h3><a class="main__anchor" name="filter" href="#filter">filter</a></h3><p>The <code>find</code> method looks for a single (first) element that makes the function return <code>true</code>.</p> <p>If there may be many, we can use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">arr.filter(fn)</a>.</p> <p>The syntax is similar to <code>find</code>, but <code>filter</code> returns an array of all matching elements:</p> <div id="9bnbur6tuz" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let results = arr.filter(function(item, index, array) { // if true item is pushed to results and the iteration continues // returns empty array if nothing found });</code></pre> </div> </div> </div><p>For instance:</p> <div id="udilrmwmgw" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let users = [ {id: 1, name: &quot;John&quot;}, {id: 2, name: &quot;Pete&quot;}, {id: 3, name: &quot;Mary&quot;} ]; // returns array of the first two users let someUsers = users.filter(item =&gt; item.id &lt; 3); alert(someUsers.length); // 2</code></pre> </div> </div> </div><h2><a class="main__anchor" name="transform-an-array" href="#transform-an-array">Transform an array</a></h2><p>Let’s move on to methods that transform and reorder an array.</p> <h3><a class="main__anchor" name="map" href="#map">map</a></h3><p>The <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">arr.map</a> method is one of the most useful and often used.</p> <p>It calls the function for each element of the array and returns the array of results.</p> <p>The syntax is:</p> <div id="izmd3agjvg" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let result = arr.map(function(item, index, array) { // returns the new value instead of item });</code></pre> </div> </div> </div><p>For instance, here we transform each element into its length:</p> <div id="w1v06geru9" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let lengths = [&quot;Bilbo&quot;, &quot;Gandalf&quot;, &quot;Nazgul&quot;].map(item =&gt; item.length); alert(lengths); // 5,7,6</code></pre> </div> </div> </div><h3><a class="main__anchor" name="sort-fn" href="#sort-fn">sort(fn)</a></h3><p>The call to <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort">arr.sort()</a> sorts the array <em>in place</em>, changing its element order.</p> <p>It also returns the sorted array, but the returned value is usually ignored, as <code>arr</code> itself is modified.</p> <p>For instance:</p> <div id="guqni60gn5" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:5,&quot;cols&quot;:[{&quot;start&quot;:18,&quot;end&quot;:26}]}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [ 1, 2, 15 ]; // the method reorders the content of arr arr.sort(); alert( arr ); // 1, 15, 2</code></pre> </div> </div> </div><p>Did you notice anything strange in the outcome?</p> <p>The order became <code>1, 15, 2</code>. Incorrect. But why?</p> <p><strong>The items are sorted as strings by default.</strong></p> <p>Literally, all elements are converted to strings for comparisons. For strings, lexicographic ordering is applied and indeed <code>&quot;2&quot; &gt; &quot;15&quot;</code>.</p> <p>To use our own sorting order, we need to supply a function as the argument of <code>arr.sort()</code>.</p> <p>The function should compare two arbitrary values and return:</p> <div id="3la4ons39r" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function compare(a, b) { if (a &gt; b) return 1; // if the first value is greater than the second if (a == b) return 0; // if values are equal if (a &lt; b) return -1; // if the first value is less than the second }</code></pre> </div> </div> </div><p>For instance, to sort as numbers:</p> <div id="dqjchph9hy" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:10,&quot;cols&quot;:[{&quot;start&quot;:16,&quot;end&quot;:24}]},{&quot;start&quot;:8,&quot;end&quot;:8}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function compareNumeric(a, b) { if (a &gt; b) return 1; if (a == b) return 0; if (a &lt; b) return -1; } let arr = [ 1, 2, 15 ]; arr.sort(compareNumeric); alert(arr); // 1, 2, 15</code></pre> </div> </div> </div><p>Now it works as intended.</p> <p>Let’s step aside and think about what’s happening. The <code>arr</code> can be an array of anything, right? It may contain numbers or strings or objects or whatever. We have a set of <em>some items</em>. To sort it, we need an <em>ordering function</em> that knows how to compare its elements. The default is a string order.</p> <p>The <code>arr.sort(fn)</code> method implements a generic sorting algorithm. We don’t need to care how it internally works (an optimized <a href="https://en.wikipedia.org/wiki/Quicksort">quicksort</a> or <a href="https://en.wikipedia.org/wiki/Timsort">Timsort</a> most of the time). It will walk the array, compare its elements using the provided function and reorder them, all we need is to provide the <code>fn</code> which does the comparison.</p> <p>By the way, if we ever want to know which elements are compared – nothing prevents us from alerting them:</p> <div id="o4t54n4akt" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>[1, -2, 15, 2, 0, 8].sort(function(a, b) { alert( a + &quot; &lt;&gt; &quot; + b ); return a - b; });</code></pre> </div> </div> </div><p>The algorithm may compare an element with multiple others in the process, but it tries to make as few comparisons as possible.</p> <div class="important important_smart"> <div class="important__header"><span class="important__type">A comparison function may return any number</span></div> <div class="important__content"><p>Actually, a comparison function is only required to return a positive number to say “greater” and a negative number to say “less”.</p> <p>That allows to write shorter functions:</p> <div id="afjunjy06k" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:4,&quot;cols&quot;:[{&quot;start&quot;:16,&quot;end&quot;:24}]}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [ 1, 2, 15 ]; arr.sort(function(a, b) { return a - b; }); alert(arr); // 1, 2, 15</code></pre> </div> </div> </div></div></div> <div class="important important_smart"> <div class="important__header"><span class="important__type">Arrow functions for the best</span></div> <div class="important__content"><p>Remember <a href="/arrow-functions-basics">arrow functions</a>? We can use them here for neater sorting:</p> <div id="cm7mof1vzj" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>arr.sort( (a, b) =&gt; a - b );</code></pre> </div> </div> </div><p>This works exactly the same as the longer version above.</p> </div></div> <div class="important important_smart"> <div class="important__header"><span class="important__type">Use <code>localeCompare</code> for strings</span></div> <div class="important__content"><p>Remember <a href="/string#correct-comparisons">strings</a> comparison algorithm? It compares letters by their codes by default.</p> <p>For many alphabets, it’s better to use <code>str.localeCompare</code> method to correctly sort letters, such as <code>Ö</code>.</p> <p>For example, let’s sort a few countries in German:</p> <div id="ktffd7ihbp" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let countries = ['Österreich', 'Andorra', 'Vietnam']; alert( countries.sort( (a, b) =&gt; a &gt; b ? 1 : -1) ); // Andorra, Vietnam, Österreich (wrong) alert( countries.sort( (a, b) =&gt; a.localeCompare(b) ) ); // Andorra,Österreich,Vietnam (correct!)</code></pre> </div> </div> </div></div></div> <h3><a class="main__anchor" name="reverse" href="#reverse">reverse</a></h3><p>The method <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse">arr.reverse</a> reverses the order of elements in <code>arr</code>.</p> <p>For instance:</p> <div id="h0exxc95zl" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [1, 2, 3, 4, 5]; arr.reverse(); alert( arr ); // 5,4,3,2,1</code></pre> </div> </div> </div><p>It also returns the array <code>arr</code> after the reversal.</p> <h3><a class="main__anchor" name="split-and-join" href="#split-and-join">split and join</a></h3><p>Here’s the situation from real life. We are writing a messaging app, and the person enters the comma-delimited list of receivers: <code>John, Pete, Mary</code>. But for us an array of names would be much more comfortable than a single string. How to get it?</p> <p>The <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">str.split(delim)</a> method does exactly that. It splits the string into an array by the given delimiter <code>delim</code>.</p> <p>In the example below, we split by a comma followed by a space:</p> <div id="kof019d1qg" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let names = 'Bilbo, Gandalf, Nazgul'; let arr = names.split(', '); for (let name of arr) { alert( `A message to ${name}.` ); // A message to Bilbo (and other names) }</code></pre> </div> </div> </div><p>The <code>split</code> method has an optional second numeric argument – a limit on the array length. If it is provided, then the extra elements are ignored. In practice it is rarely used though:</p> <div id="5osybjyqyw" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = 'Bilbo, Gandalf, Nazgul, Saruman'.split(', ', 2); alert(arr); // Bilbo, Gandalf</code></pre> </div> </div> </div><div class="important important_smart"> <div class="important__header"><span class="important__type">Split into letters</span></div> <div class="important__content"><p>The call to <code>split(s)</code> with an empty <code>s</code> would split the string into an array of letters:</p> <div id="pcms16vv1h" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let str = &quot;test&quot;; alert( str.split('') ); // t,e,s,t</code></pre> </div> </div> </div></div></div> <p>The call <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join">arr.join(glue)</a> does the reverse to <code>split</code>. It creates a string of <code>arr</code> items joined by <code>glue</code> between them.</p> <p>For instance:</p> <div id="lraqdgzmaz" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = ['Bilbo', 'Gandalf', 'Nazgul']; let str = arr.join(';'); // glue the array into a string using ; alert( str ); // Bilbo;Gandalf;Nazgul</code></pre> </div> </div> </div><h3><a class="main__anchor" name="reduce-reduceright" href="#reduce-reduceright">reduce/reduceRight</a></h3><p>When we need to iterate over an array – we can use <code>forEach</code>, <code>for</code> or <code>for..of</code>.</p> <p>When we need to iterate and return the data for each element – we can use <code>map</code>.</p> <p>The methods <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce">arr.reduce</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight">arr.reduceRight</a> also belong to that breed, but are a little bit more intricate. They are used to calculate a single value based on the array.</p> <p>The syntax is:</p> <div id="op3qbuj3j4" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let value = arr.reduce(function(accumulator, item, index, array) { // ... }, [initial]);</code></pre> </div> </div> </div><p>The function is applied to all array elements one after another and “carries on” its result to the next call.</p> <p>Arguments:</p> <ul> <li><code>accumulator</code> – is the result of the previous function call, equals <code>initial</code> the first time (if <code>initial</code> is provided).</li> <li><code>item</code> – is the current array item.</li> <li><code>index</code> – is its position.</li> <li><code>array</code> – is the array.</li> </ul> <p>As the function is applied, the result of the previous function call is passed to the next one as the first argument.</p> <p>So, the first argument is essentially the accumulator that stores the combined result of all previous executions. And at the end, it becomes the result of <code>reduce</code>.</p> <p>Sounds complicated?</p> <p>The easiest way to grasp that is by example.</p> <p>Here we get a sum of an array in one line:</p> <div id="pq04vabgu0" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [1, 2, 3, 4, 5]; let result = arr.reduce((sum, current) =&gt; sum + current, 0); alert(result); // 15</code></pre> </div> </div> </div><p>The function passed to <code>reduce</code> uses only 2 arguments, that’s typically enough.</p> <p>Let’s see the details of what’s going on.</p> <ol> <li>On the first run, <code>sum</code> is the <code>initial</code> value (the last argument of <code>reduce</code>), equals <code>0</code>, and <code>current</code> is the first array element, equals <code>1</code>. So the function result is <code>1</code>.</li> <li>On the second run, <code>sum = 1</code>, we add the second array element (<code>2</code>) to it and return.</li> <li>On the 3rd run, <code>sum = 3</code> and we add one more element to it, and so on…</li> </ol> <p>The calculation flow:</p> <figure><div class="image" style="width:620px"> <div class="image__ratio" style="padding-top:20.806451612903228%"></div> <object type="image/svg+xml" data="/article/array-methods/reduce.svg" width="620" height="129" class="image__image" data-use-theme> <img src="/article/array-methods/reduce.svg" alt="" width="620" height="129"> </object> </div></figure><p>Or in the form of a table, where each row represents a function call on the next array element:</p> <table> <thead> <tr> <th></th> <th><code>sum</code></th> <th><code>current</code></th> <th>result</th> </tr> </thead> <tbody> <tr> <td>the first call</td> <td><code>0</code></td> <td><code>1</code></td> <td><code>1</code></td> </tr> <tr> <td>the second call</td> <td><code>1</code></td> <td><code>2</code></td> <td><code>3</code></td> </tr> <tr> <td>the third call</td> <td><code>3</code></td> <td><code>3</code></td> <td><code>6</code></td> </tr> <tr> <td>the fourth call</td> <td><code>6</code></td> <td><code>4</code></td> <td><code>10</code></td> </tr> <tr> <td>the fifth call</td> <td><code>10</code></td> <td><code>5</code></td> <td><code>15</code></td> </tr> </tbody> </table> <p>Here we can clearly see how the result of the previous call becomes the first argument of the next one.</p> <p>We also can omit the initial value:</p> <div id="i0gslnugje" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [1, 2, 3, 4, 5]; // removed initial value from reduce (no 0) let result = arr.reduce((sum, current) =&gt; sum + current); alert( result ); // 15</code></pre> </div> </div> </div><p>The result is the same. That’s because if there’s no initial, then <code>reduce</code> takes the first element of the array as the initial value and starts the iteration from the 2nd element.</p> <p>The calculation table is the same as above, minus the first row.</p> <p>But such use requires an extreme care. If the array is empty, then <code>reduce</code> call without initial value gives an error.</p> <p>Here’s an example:</p> <div id="1j9amarm0y" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = []; // Error: Reduce of empty array with no initial value // if the initial value existed, reduce would return it for the empty arr. arr.reduce((sum, current) =&gt; sum + current);</code></pre> </div> </div> </div><p>So it’s advised to always specify the initial value.</p> <p>The method <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight">arr.reduceRight</a> does the same but goes from right to left.</p> <h2><a class="main__anchor" name="array-isarray" href="#array-isarray">Array.isArray</a></h2><p>Arrays do not form a separate language type. They are based on objects.</p> <p>So <code>typeof</code> does not help to distinguish a plain object from an array:</p> <div id="qgxsdonof1" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>alert(typeof {}); // object alert(typeof []); // object (same)</code></pre> </div> </div> </div><p>…But arrays are used so often that there’s a special method for that: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray">Array.isArray(value)</a>. It returns <code>true</code> if the <code>value</code> is an array, and <code>false</code> otherwise.</p> <div id="5oqnecm7ad" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>alert(Array.isArray({})); // false alert(Array.isArray([])); // true</code></pre> </div> </div> </div><h2><a class="main__anchor" name="most-methods-support-thisarg" href="#most-methods-support-thisarg">Most methods support “thisArg”</a></h2><p>Almost all array methods that call functions – like <code>find</code>, <code>filter</code>, <code>map</code>, with a notable exception of <code>sort</code>, accept an optional additional parameter <code>thisArg</code>.</p> <p>That parameter is not explained in the sections above, because it’s rarely used. But for completeness, we have to cover it.</p> <p>Here’s the full syntax of these methods:</p> <div id="5vyfdcd8xs" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>arr.find(func, thisArg); arr.filter(func, thisArg); arr.map(func, thisArg); // ... // thisArg is the optional last argument</code></pre> </div> </div> </div><p>The value of <code>thisArg</code> parameter becomes <code>this</code> for <code>func</code>.</p> <p>For example, here we use a method of <code>army</code> object as a filter, and <code>thisArg</code> passes the context:</p> <div id="zdczwitymc" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:15,&quot;end&quot;:16}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let army = { minAge: 18, maxAge: 27, canJoin(user) { return user.age &gt;= this.minAge &amp;&amp; user.age &lt; this.maxAge; } }; let users = [ {age: 16}, {age: 20}, {age: 23}, {age: 30} ]; // find users, for who army.canJoin returns true let soldiers = users.filter(army.canJoin, army); alert(soldiers.length); // 2 alert(soldiers[0].age); // 20 alert(soldiers[1].age); // 23</code></pre> </div> </div> </div><p>If in the example above we used <code>users.filter(army.canJoin)</code>, then <code>army.canJoin</code> would be called as a standalone function, with <code>this=undefined</code>, thus leading to an instant error.</p> <p>A call to <code>users.filter(army.canJoin, army)</code> can be replaced with <code>users.filter(user =&gt; army.canJoin(user))</code>, that does the same. The latter is used more often, as it’s a bit easier to understand for most people.</p> <h2><a class="main__anchor" name="summary" href="#summary">Summary</a></h2><p>A cheat sheet of array methods:</p> <ul> <li> <p>To add/remove elements:</p> <ul> <li><code>push(...items)</code> – adds items to the end,</li> <li><code>pop()</code> – extracts an item from the end,</li> <li><code>shift()</code> – extracts an item from the beginning,</li> <li><code>unshift(...items)</code> – adds items to the beginning.</li> <li><code>splice(pos, deleteCount, ...items)</code> – at index <code>pos</code> deletes <code>deleteCount</code> elements and inserts <code>items</code>.</li> <li><code>slice(start, end)</code> – creates a new array, copies elements from index <code>start</code> till <code>end</code> (not inclusive) into it.</li> <li><code>concat(...items)</code> – returns a new array: copies all members of the current one and adds <code>items</code> to it. If any of <code>items</code> is an array, then its elements are taken.</li> </ul> </li> <li> <p>To search among elements:</p> <ul> <li><code>indexOf/lastIndexOf(item, pos)</code> – look for <code>item</code> starting from position <code>pos</code>, and return the index or <code>-1</code> if not found.</li> <li><code>includes(value)</code> – returns <code>true</code> if the array has <code>value</code>, otherwise <code>false</code>.</li> <li><code>find/filter(func)</code> – filter elements through the function, return first/all values that make it return <code>true</code>.</li> <li><code>findIndex</code> is like <code>find</code>, but returns the index instead of a value.</li> </ul> </li> <li> <p>To iterate over elements:</p> <ul> <li><code>forEach(func)</code> – calls <code>func</code> for every element, does not return anything.</li> </ul> </li> <li> <p>To transform the array:</p> <ul> <li><code>map(func)</code> – creates a new array from results of calling <code>func</code> for every element.</li> <li><code>sort(func)</code> – sorts the array in-place, then returns it.</li> <li><code>reverse()</code> – reverses the array in-place, then returns it.</li> <li><code>split/join</code> – convert a string to array and back.</li> <li><code>reduce/reduceRight(func, initial)</code> – calculate a single value over the array by calling <code>func</code> for each element and passing an intermediate result between the calls.</li> </ul> </li> <li> <p>Additionally:</p> <ul> <li><code>Array.isArray(value)</code> checks <code>value</code> for being an array, if so returns <code>true</code>, otherwise <code>false</code>.</li> </ul> </li> </ul> <p>Please note that methods <code>sort</code>, <code>reverse</code> and <code>splice</code> modify the array itself.</p> <p>These methods are the most used ones, they cover 99% of use cases. But there are few others:</p> <ul> <li> <p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some">arr.some(fn)</a>/<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every">arr.every(fn)</a> check the array.</p> <p>The function <code>fn</code> is called on each element of the array similar to <code>map</code>. If any/all results are <code>true</code>, returns <code>true</code>, otherwise <code>false</code>.</p> <p>These methods behave sort of like <code>||</code> and <code>&amp;&amp;</code> operators: if <code>fn</code> returns a truthy value, <code>arr.some()</code> immediately returns <code>true</code> and stops iterating over the rest of items; if <code>fn</code> returns a falsy value, <code>arr.every()</code> immediately returns <code>false</code> and stops iterating over the rest of items as well.</p> <p>We can use <code>every</code> to compare arrays:</p> <div id="2kqrikfkh8" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function arraysEqual(arr1, arr2) { return arr1.length === arr2.length &amp;&amp; arr1.every((value, index) =&gt; value === arr2[index]); } alert( arraysEqual([1, 2], [1, 2])); // true</code></pre> </div> </div> </div></li> <li> <p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill">arr.fill(value, start, end)</a> – fills the array with repeating <code>value</code> from index <code>start</code> to <code>end</code>.</p> </li> <li> <p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin">arr.copyWithin(target, start, end)</a> – copies its elements from position <code>start</code> till position <code>end</code> into <em>itself</em>, at position <code>target</code> (overwrites existing).</p> </li> <li> <p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat">arr.flat(depth)</a>/<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap">arr.flatMap(fn)</a> create a new flat array from a multidimensional array.</p> </li> </ul> <p>For the full list, see the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">manual</a>.</p> <p>At first sight, it may seem that there are so many methods, quite difficult to remember. But actually, that’s much easier.</p> <p>Look through the cheat sheet just to be aware of them. Then solve the tasks of this chapter to practice, so that you have experience with array methods.</p> <p>Afterwards whenever you need to do something with an array, and you don’t know how – come here, look at the cheat sheet and find the right method. Examples will help you to write it correctly. Soon you’ll automatically remember the methods, without specific efforts from your side.</p> </div></article><div class="tasks formatted"><h2 class="tasks__title" id="tasks"><a class="tasks__title-anchor main__anchor main__anchor main__anchor_noicon" href="#tasks">Tasks</a></h2><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#translate-border-left-width-to-borderleftwidth" name="translate-border-left-width-to-borderleftwidth">Translate border-left-width to borderLeftWidth</a></h3><a class="task__open-link" href="/task/camelcase" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 5</span></div><div class="task__content"><div class="task__formatted"><p>Write the function <code>camelize(str)</code> that changes dash-separated words like “my-short-string” into camel-cased “myShortString”.</p> <p>That is: removes all dashes, each word after dash becomes uppercased.</p> <p>Examples:</p> <div id="37vmdr7bdy" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>camelize(&quot;background-color&quot;) == 'backgroundColor'; camelize(&quot;list-style-image&quot;) == 'listStyleImage'; camelize(&quot;-webkit-transition&quot;) == 'WebkitTransition';</code></pre> </div> </div> </div><p>P.S. Hint: use <code>split</code> to split the string into an array, transform it and <code>join</code> back.</p> <p><a href="https://plnkr.co/edit/dAF0dZ4YJPWUo1fa?p=preview" target="_blank" data-plunk-id="dAF0dZ4YJPWUo1fa">Open a sandbox with tests.</a></p></div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="erdk0gkc2k" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function camelize(str) { return str .split('-') // splits 'my-long-word' into array ['my', 'long', 'word'] .map( // capitalizes first letters of all array items except the first one // converts ['my', 'long', 'word'] into ['my', 'Long', 'Word'] (word, index) =&gt; index == 0 ? word : word[0].toUpperCase() + word.slice(1) ) .join(''); // joins ['my', 'Long', 'Word'] into 'myLongWord' }</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/g0rn2sRMwfr1CM0a?p=preview" target="_blank" data-plunk-id="g0rn2sRMwfr1CM0a">Open the solution with tests in a sandbox.</a></p></div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#filter-range" name="filter-range">Filter range</a></h3><a class="task__open-link" href="/task/filter-range" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 4</span></div><div class="task__content"><div class="task__formatted"><p>Write a function <code>filterRange(arr, a, b)</code> that gets an array <code>arr</code>, looks for elements with values higher or equal to <code>a</code> and lower or equal to <code>b</code> and return a result as an array.</p> <p>The function should not modify the array. It should return the new array.</p> <p>For instance:</p> <div id="xdeafio2x7" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [5, 3, 8, 1]; let filtered = filterRange(arr, 1, 4); alert( filtered ); // 3,1 (matching values) alert( arr ); // 5,3,8,1 (not modified)</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/qw1z3b5aNgvbQOMQ?p=preview" target="_blank" data-plunk-id="qw1z3b5aNgvbQOMQ">Open a sandbox with tests.</a></p></div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="t4svbl39ir" data-trusted="1" class="code-example" data-demo="1"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function filterRange(arr, a, b) { // added brackets around the expression for better readability return arr.filter(item =&gt; (a &lt;= item &amp;&amp; item &lt;= b)); } let arr = [5, 3, 8, 1]; let filtered = filterRange(arr, 1, 4); alert( filtered ); // 3,1 (matching values) alert( arr ); // 5,3,8,1 (not modified)</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/laSpPelqqxEKI5n3?p=preview" target="_blank" data-plunk-id="laSpPelqqxEKI5n3">Open the solution with tests in a sandbox.</a></p></div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#filter-range-in-place" name="filter-range-in-place">Filter range &quot;in place&quot;</a></h3><a class="task__open-link" href="/task/filter-range-in-place" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 4</span></div><div class="task__content"><div class="task__formatted"><p>Write a function <code>filterRangeInPlace(arr, a, b)</code> that gets an array <code>arr</code> and removes from it all values except those that are between <code>a</code> and <code>b</code>. The test is: <code>a ≤ arr[i] ≤ b</code>.</p> <p>The function should only modify the array. It should not return anything.</p> <p>For instance:</p> <div id="xb1w90zao8" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [5, 3, 8, 1]; filterRangeInPlace(arr, 1, 4); // removed the numbers except from 1 to 4 alert( arr ); // [3, 1]</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/34AaQvUB4VBEpPu1?p=preview" target="_blank" data-plunk-id="34AaQvUB4VBEpPu1">Open a sandbox with tests.</a></p></div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="dlsmstan25" data-trusted="1" class="code-example" data-demo="1"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function filterRangeInPlace(arr, a, b) { for (let i = 0; i &lt; arr.length; i++) { let val = arr[i]; // remove if outside of the interval if (val &lt; a || val &gt; b) { arr.splice(i, 1); i--; } } } let arr = [5, 3, 8, 1]; filterRangeInPlace(arr, 1, 4); // removed the numbers except from 1 to 4 alert( arr ); // [3, 1]</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/j80aBKHMgBo6i5SE?p=preview" target="_blank" data-plunk-id="j80aBKHMgBo6i5SE">Open the solution with tests in a sandbox.</a></p></div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#sort-in-decreasing-order" name="sort-in-decreasing-order">Sort in decreasing order</a></h3><a class="task__open-link" href="/task/sort-back" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 4</span></div><div class="task__content"><div class="task__formatted"><div id="gvfupjddqp" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [5, 2, 1, -10, 8]; // ... your code to sort it in decreasing order alert( arr ); // 8, 5, 2, 1, -10</code></pre> </div> </div> </div></div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="6udbk26yj3" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [5, 2, 1, -10, 8]; arr.sort((a, b) =&gt; b - a); alert( arr );</code></pre> </div> </div> </div></div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#copy-and-sort-array" name="copy-and-sort-array">Copy and sort array</a></h3><a class="task__open-link" href="/task/copy-sort-array" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 5</span></div><div class="task__content"><div class="task__formatted"><p>We have an array of strings <code>arr</code>. We’d like to have a sorted copy of it, but keep <code>arr</code> unmodified.</p> <p>Create a function <code>copySorted(arr)</code> that returns such a copy.</p> <div id="8g59vj5ceh" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [&quot;HTML&quot;, &quot;JavaScript&quot;, &quot;CSS&quot;]; let sorted = copySorted(arr); alert( sorted ); // CSS, HTML, JavaScript alert( arr ); // HTML, JavaScript, CSS (no changes)</code></pre> </div> </div> </div></div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><p>We can use <code>slice()</code> to make a copy and run the sort on it:</p> <div id="okgrkpj9ty" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:6,&quot;end&quot;:6}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function copySorted(arr) { return arr.slice().sort(); } let arr = [&quot;HTML&quot;, &quot;JavaScript&quot;, &quot;CSS&quot;]; let sorted = copySorted(arr); alert( sorted ); alert( arr );</code></pre> </div> </div> </div></div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#create-an-extendable-calculator" name="create-an-extendable-calculator">Create an extendable calculator</a></h3><a class="task__open-link" href="/task/calculator-extendable" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 5</span></div><div class="task__content"><div class="task__formatted"><p>Create a constructor function <code>Calculator</code> that creates “extendable” calculator objects.</p> <p>The task consists of two parts.</p> <ol> <li> <p>First, implement the method <code>calculate(str)</code> that takes a string like <code>&quot;1 + 2&quot;</code> in the format “NUMBER operator NUMBER” (space-delimited) and returns the result. Should understand plus <code>+</code> and minus <code>-</code>.</p> <p>Usage example:</p> <div id="cr0uiv5o9o" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let calc = new Calculator; alert( calc.calculate(&quot;3 + 7&quot;) ); // 10</code></pre> </div> </div> </div></li> <li> <p>Then add the method <code>addMethod(name, func)</code> that teaches the calculator a new operation. It takes the operator <code>name</code> and the two-argument function <code>func(a,b)</code> that implements it.</p> <p>For instance, let’s add the multiplication <code>*</code>, division <code>/</code> and power <code>**</code>:</p> <div id="wka9z7t2r1" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let powerCalc = new Calculator; powerCalc.addMethod(&quot;*&quot;, (a, b) =&gt; a * b); powerCalc.addMethod(&quot;/&quot;, (a, b) =&gt; a / b); powerCalc.addMethod(&quot;**&quot;, (a, b) =&gt; a ** b); let result = powerCalc.calculate(&quot;2 ** 3&quot;); alert( result ); // 8</code></pre> </div> </div> </div></li> </ol> <ul> <li>No parentheses or complex expressions in this task.</li> <li>The numbers and the operator are delimited with exactly one space.</li> <li>There may be error handling if you’d like to add it.</li> </ul> <p><a href="https://plnkr.co/edit/A5OT4UUNYiIOziiQ?p=preview" target="_blank" data-plunk-id="A5OT4UUNYiIOziiQ">Open a sandbox with tests.</a></p></div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><ul> <li>Please note how methods are stored. They are simply added to <code>this.methods</code> property.</li> <li>All tests and numeric conversions are done in the <code>calculate</code> method. In future it may be extended to support more complex expressions.</li> </ul> <div id="sjhg73k1qv" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function Calculator() { this.methods = { &quot;-&quot;: (a, b) =&gt; a - b, &quot;+&quot;: (a, b) =&gt; a + b }; this.calculate = function(str) { let split = str.split(' '), a = +split[0], op = split[1], b = +split[2]; if (!this.methods[op] || isNaN(a) || isNaN(b)) { return NaN; } return this.methods[op](a, b); }; this.addMethod = function(name, func) { this.methods[name] = func; }; }</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/ITgICzRf4STvCgso?p=preview" target="_blank" data-plunk-id="ITgICzRf4STvCgso">Open the solution with tests in a sandbox.</a></p></div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#map-to-names" name="map-to-names">Map to names</a></h3><a class="task__open-link" href="/task/array-get-names" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 5</span></div><div class="task__content"><div class="task__formatted"><p>You have an array of <code>user</code> objects, each one has <code>user.name</code>. Write the code that converts it into an array of names.</p> <p>For instance:</p> <div id="fyu9xmgjrq" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let john = { name: &quot;John&quot;, age: 25 }; let pete = { name: &quot;Pete&quot;, age: 30 }; let mary = { name: &quot;Mary&quot;, age: 28 }; let users = [ john, pete, mary ]; let names = /* ... your code */ alert( names ); // John, Pete, Mary</code></pre> </div> </div> </div></div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="4cnbwmikzh" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let john = { name: &quot;John&quot;, age: 25 }; let pete = { name: &quot;Pete&quot;, age: 30 }; let mary = { name: &quot;Mary&quot;, age: 28 }; let users = [ john, pete, mary ]; let names = users.map(item =&gt; item.name); alert( names ); // John, Pete, Mary</code></pre> </div> </div> </div></div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#map-to-objects" name="map-to-objects">Map to objects</a></h3><a class="task__open-link" href="/task/map-objects" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 5</span></div><div class="task__content"><div class="task__formatted"><p>You have an array of <code>user</code> objects, each one has <code>name</code>, <code>surname</code> and <code>id</code>.</p> <p>Write the code to create another array from it, of objects with <code>id</code> and <code>fullName</code>, where <code>fullName</code> is generated from <code>name</code> and <code>surname</code>.</p> <p>For instance:</p> <div id="sap0duv4s5" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:6,&quot;end&quot;:6}]"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let john = { name: &quot;John&quot;, surname: &quot;Smith&quot;, id: 1 }; let pete = { name: &quot;Pete&quot;, surname: &quot;Hunt&quot;, id: 2 }; let mary = { name: &quot;Mary&quot;, surname: &quot;Key&quot;, id: 3 }; let users = [ john, pete, mary ]; let usersMapped = /* ... your code ... */ /* usersMapped = [ { fullName: &quot;John Smith&quot;, id: 1 }, { fullName: &quot;Pete Hunt&quot;, id: 2 }, { fullName: &quot;Mary Key&quot;, id: 3 } ] */ alert( usersMapped[0].id ) // 1 alert( usersMapped[0].fullName ) // John Smith</code></pre> </div> </div> </div><p>So, actually you need to map one array of objects to another. Try using <code>=&gt;</code> here. There’s a small catch.</p> </div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="ske720b2am" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:6,&quot;end&quot;:9}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let john = { name: &quot;John&quot;, surname: &quot;Smith&quot;, id: 1 }; let pete = { name: &quot;Pete&quot;, surname: &quot;Hunt&quot;, id: 2 }; let mary = { name: &quot;Mary&quot;, surname: &quot;Key&quot;, id: 3 }; let users = [ john, pete, mary ]; let usersMapped = users.map(user =&gt; ({ fullName: `${user.name} ${user.surname}`, id: user.id })); /* usersMapped = [ { fullName: &quot;John Smith&quot;, id: 1 }, { fullName: &quot;Pete Hunt&quot;, id: 2 }, { fullName: &quot;Mary Key&quot;, id: 3 } ] */ alert( usersMapped[0].id ); // 1 alert( usersMapped[0].fullName ); // John Smith</code></pre> </div> </div> </div><p>Please note that in the arrow functions we need to use additional brackets.</p> <p>We can’t write like this:</p> <div id="xifd93zn41" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:0,&quot;cols&quot;:[{&quot;start&quot;:36,&quot;end&quot;:37}]}]"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let usersMapped = users.map(user =&gt; { fullName: `${user.name} ${user.surname}`, id: user.id });</code></pre> </div> </div> </div><p>As we remember, there are two arrow functions: without body <code>value =&gt; expr</code> and with body <code>value =&gt; {...}</code>.</p> <p>Here JavaScript would treat <code>{</code> as the start of function body, not the start of the object. The workaround is to wrap them in the “normal” brackets:</p> <div id="p74lw485sq" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:0,&quot;cols&quot;:[{&quot;start&quot;:36,&quot;end&quot;:38}]}]"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let usersMapped = users.map(user =&gt; ({ fullName: `${user.name} ${user.surname}`, id: user.id }));</code></pre> </div> </div> </div><p>Now fine.</p> </div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#sort-users-by-age" name="sort-users-by-age">Sort users by age</a></h3><a class="task__open-link" href="/task/sort-objects" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 5</span></div><div class="task__content"><div class="task__formatted"><p>Write the function <code>sortByAge(users)</code> that gets an array of objects with the <code>age</code> property and sorts them by <code>age</code>.</p> <p>For instance:</p> <div id="g8qcyfdsib" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let john = { name: &quot;John&quot;, age: 25 }; let pete = { name: &quot;Pete&quot;, age: 30 }; let mary = { name: &quot;Mary&quot;, age: 28 }; let arr = [ pete, john, mary ]; sortByAge(arr); // now: [john, mary, pete] alert(arr[0].name); // John alert(arr[1].name); // Mary alert(arr[2].name); // Pete</code></pre> </div> </div> </div></div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="raacfthqfp" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function sortByAge(arr) { arr.sort((a, b) =&gt; a.age - b.age); } let john = { name: &quot;John&quot;, age: 25 }; let pete = { name: &quot;Pete&quot;, age: 30 }; let mary = { name: &quot;Mary&quot;, age: 28 }; let arr = [ pete, john, mary ]; sortByAge(arr); // now sorted is: [john, mary, pete] alert(arr[0].name); // John alert(arr[1].name); // Mary alert(arr[2].name); // Pete</code></pre> </div> </div> </div></div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#shuffle-an-array" name="shuffle-an-array">Shuffle an array</a></h3><a class="task__open-link" href="/task/shuffle" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 3</span></div><div class="task__content"><div class="task__formatted"><p>Write the function <code>shuffle(array)</code> that shuffles (randomly reorders) elements of the array.</p> <p>Multiple runs of <code>shuffle</code> may lead to different orders of elements. For instance:</p> <div id="k5ue8iddo8" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let arr = [1, 2, 3]; shuffle(arr); // arr = [3, 2, 1] shuffle(arr); // arr = [2, 1, 3] shuffle(arr); // arr = [3, 1, 2] // ...</code></pre> </div> </div> </div><p>All element orders should have an equal probability. For instance, <code>[1,2,3]</code> can be reordered as <code>[1,2,3]</code> or <code>[1,3,2]</code> or <code>[3,1,2]</code> etc, with equal probability of each case.</p> </div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><p>The simple solution could be:</p> <div id="w8rg1toy3a" data-trusted="1" class="code-example" data-highlight="[{&quot;start&quot;:0,&quot;end&quot;:2}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function shuffle(array) { array.sort(() =&gt; Math.random() - 0.5); } let arr = [1, 2, 3]; shuffle(arr); alert(arr);</code></pre> </div> </div> </div><p>That somewhat works, because <code>Math.random() - 0.5</code> is a random number that may be positive or negative, so the sorting function reorders elements randomly.</p> <p>But because the sorting function is not meant to be used this way, not all permutations have the same probability.</p> <p>For instance, consider the code below. It runs <code>shuffle</code> 1000000 times and counts appearances of all possible results:</p> <div id="r4kjtby5hk" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function shuffle(array) { array.sort(() =&gt; Math.random() - 0.5); } // counts of appearances for all possible permutations let count = { '123': 0, '132': 0, '213': 0, '231': 0, '321': 0, '312': 0 }; for (let i = 0; i &lt; 1000000; i++) { let array = [1, 2, 3]; shuffle(array); count[array.join('')]++; } // show counts of all possible permutations for (let key in count) { alert(`${key}: ${count[key]}`); }</code></pre> </div> </div> </div><p>An example result (depends on JS engine):</p> <div id="azf8ooopcp" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>123: 250706 132: 124425 213: 249618 231: 124880 312: 125148 321: 125223</code></pre> </div> </div> </div><p>We can see the bias clearly: <code>123</code> and <code>213</code> appear much more often than others.</p> <p>The result of the code may vary between JavaScript engines, but we can already see that the approach is unreliable.</p> <p>Why it doesn’t work? Generally speaking, <code>sort</code> is a “black box”: we throw an array and a comparison function into it and expect the array to be sorted. But due to the utter randomness of the comparison the black box goes mad, and how exactly it goes mad depends on the concrete implementation that differs between engines.</p> <p>There are other good ways to do the task. For instance, there’s a great algorithm called <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle</a>. The idea is to walk the array in the reverse order and swap each element with a random one before it:</p> <div id="14cralakkm" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function shuffle(array) { for (let i = array.length - 1; i &gt; 0; i--) { let j = Math.floor(Math.random() * (i + 1)); // random index from 0 to i // swap elements array[i] and array[j] // we use &quot;destructuring assignment&quot; syntax to achieve that // you'll find more details about that syntax in later chapters // same can be written as: // let t = array[i]; array[i] = array[j]; array[j] = t [array[i], array[j]] = [array[j], array[i]]; } }</code></pre> </div> </div> </div><p>Let’s test it the same way:</p> <div id="nefwlwc61i" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function shuffle(array) { for (let i = array.length - 1; i &gt; 0; i--) { let j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } } // counts of appearances for all possible permutations let count = { '123': 0, '132': 0, '213': 0, '231': 0, '321': 0, '312': 0 }; for (let i = 0; i &lt; 1000000; i++) { let array = [1, 2, 3]; shuffle(array); count[array.join('')]++; } // show counts of all possible permutations for (let key in count) { alert(`${key}: ${count[key]}`); }</code></pre> </div> </div> </div><p>The example output:</p> <div id="l3juau06g5" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>123: 166693 132: 166647 213: 166628 231: 167517 312: 166199 321: 166316</code></pre> </div> </div> </div><p>Looks good now: all permutations appear with the same probability.</p> <p>Also, performance-wise the Fisher-Yates algorithm is much better, there’s no “sorting” overhead.</p> </div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#get-average-age" name="get-average-age">Get average age</a></h3><a class="task__open-link" href="/task/average-age" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 4</span></div><div class="task__content"><div class="task__formatted"><p>Write the function <code>getAverageAge(users)</code> that gets an array of objects with property <code>age</code> and returns the average age.</p> <p>The formula for the average is <code>(age1 + age2 + ... + ageN) / N</code>.</p> <p>For instance:</p> <div id="ifx6m2wtvq" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let john = { name: &quot;John&quot;, age: 25 }; let pete = { name: &quot;Pete&quot;, age: 30 }; let mary = { name: &quot;Mary&quot;, age: 29 }; let arr = [ john, pete, mary ]; alert( getAverageAge(arr) ); // (25 + 30 + 29) / 3 = 28</code></pre> </div> </div> </div></div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="fk2ayhjzm4" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function getAverageAge(users) { return users.reduce((prev, user) =&gt; prev + user.age, 0) / users.length; } let john = { name: &quot;John&quot;, age: 25 }; let pete = { name: &quot;Pete&quot;, age: 30 }; let mary = { name: &quot;Mary&quot;, age: 29 }; let arr = [ john, pete, mary ]; alert( getAverageAge(arr) ); // 28</code></pre> </div> </div> </div></div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#filter-unique-array-members" name="filter-unique-array-members">Filter unique array members</a></h3><a class="task__open-link" href="/task/array-unique" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 4</span></div><div class="task__content"><div class="task__formatted"><p>Let <code>arr</code> be an array.</p> <p>Create a function <code>unique(arr)</code> that should return an array with unique items of <code>arr</code>.</p> <p>For instance:</p> <div id="n7icy16max" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function unique(arr) { /* your code */ } let strings = [&quot;Hare&quot;, &quot;Krishna&quot;, &quot;Hare&quot;, &quot;Krishna&quot;, &quot;Krishna&quot;, &quot;Krishna&quot;, &quot;Hare&quot;, &quot;Hare&quot;, &quot;:-O&quot; ]; alert( unique(strings) ); // Hare, Krishna, :-O</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/mFMUjLrwRvMtnn3X?p=preview" target="_blank" data-plunk-id="mFMUjLrwRvMtnn3X">Open a sandbox with tests.</a></p></div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><p>Let’s walk the array items:</p> <ul> <li>For each item we’ll check if the resulting array already has that item.</li> <li>If it is so, then ignore, otherwise add to results.</li> </ul> <div id="vts8npdudu" data-trusted="1" class="code-example" data-demo="1"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="run" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="open in sandbox" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function unique(arr) { let result = []; for (let str of arr) { if (!result.includes(str)) { result.push(str); } } return result; } let strings = [&quot;Hare&quot;, &quot;Krishna&quot;, &quot;Hare&quot;, &quot;Krishna&quot;, &quot;Krishna&quot;, &quot;Krishna&quot;, &quot;Hare&quot;, &quot;Hare&quot;, &quot;:-O&quot; ]; alert( unique(strings) ); // Hare, Krishna, :-O</code></pre> </div> </div> </div><p>The code works, but there’s a potential performance problem in it.</p> <p>The method <code>result.includes(str)</code> internally walks the array <code>result</code> and compares each element against <code>str</code> to find the match.</p> <p>So if there are <code>100</code> elements in <code>result</code> and no one matches <code>str</code>, then it will walk the whole <code>result</code> and do exactly <code>100</code> comparisons. And if <code>result</code> is large, like <code>10000</code>, then there would be <code>10000</code> comparisons.</p> <p>That’s not a problem by itself, because JavaScript engines are very fast, so walk <code>10000</code> array is a matter of microseconds.</p> <p>But we do such test for each element of <code>arr</code>, in the <code>for</code> loop.</p> <p>So if <code>arr.length</code> is <code>10000</code> we’ll have something like <code>10000*10000</code> = 100 millions of comparisons. That’s a lot.</p> <p>So the solution is only good for small arrays.</p> <p>Further in the chapter <a href="/map-set">Map and Set</a> we’ll see how to optimize it.</p> <p><a href="https://plnkr.co/edit/OzceFOlUD2uLSUkZ?p=preview" target="_blank" data-plunk-id="OzceFOlUD2uLSUkZ">Open the solution with tests in a sandbox.</a></p></div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#create-keyed-object-from-array" name="create-keyed-object-from-array">Create keyed object from array</a></h3><a class="task__open-link" href="/task/reduce-object" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="How important is the task, from 1 to 5">importance: 4</span></div><div class="task__content"><div class="task__formatted"><p>Let’s say we received an array of users in the form <code>{id:..., name:..., age:... }</code>.</p> <p>Create a function <code>groupById(arr)</code> that creates an object from it, with <code>id</code> as the key, and array items as values.</p> <p>For example:</p> <div id="odeeawzgci" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let users = [ {id: 'john', name: &quot;John Smith&quot;, age: 20}, {id: 'ann', name: &quot;Ann Smith&quot;, age: 24}, {id: 'pete', name: &quot;Pete Peterson&quot;, age: 31}, ]; let usersById = groupById(users); /* // after the call we should have: usersById = { john: {id: 'john', name: &quot;John Smith&quot;, age: 20}, ann: {id: 'ann', name: &quot;Ann Smith&quot;, age: 24}, pete: {id: 'pete', name: &quot;Pete Peterson&quot;, age: 31}, } */</code></pre> </div> </div> </div><p>Such function is really handy when working with server data.</p> <p>In this task we assume that <code>id</code> is unique. There may be no two array items with the same <code>id</code>.</p> <p>Please use array <code>.reduce</code> method in the solution.</p> <p><a href="https://plnkr.co/edit/ShPqltMuCH00bAlM?p=preview" target="_blank" data-plunk-id="ShPqltMuCH00bAlM">Open a sandbox with tests.</a></p></div><button class="task__solution" type="button">solution</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="26ernxned2" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function groupById(array) { return array.reduce((obj, value) =&gt; { obj[value.id] = value; return obj; }, {}) }</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/PRYORtEl1Sm930JM?p=preview" target="_blank" data-plunk-id="PRYORtEl1Sm930JM">Open the solution with tests in a sandbox.</a></p></div></div><button class="close-button task__answer-close" type="button" title="close"></button></div></div></div></div></div></div><div class="page__nav-wrap"><a class="page__nav page__nav_prev" href="/array" data-tooltip="Arrays"><span class="page__nav-text"><span class="page__nav-text-shortcut"></span></span><span class="page__nav-text-alternate">Previous lesson</span></a><a class="page__nav page__nav_next" href="/iterable" data-tooltip="Iterables"><span class="page__nav-text"><span class="page__nav-text-shortcut"></span></span><span class="page__nav-text-alternate">Next lesson</span></a></div><div class="article-tablet-foot tablet-only"><div class="article-tablet-foot__layout"><div class="share-icons"><span class="share-icons__title">Share</span><a class="share share_tw" href="https://twitter.com/share?url=https%3A%2F%2Fjavascript.info%2Farray-methods" rel="nofollow"></a><a class="share share_fb" href="https://www.facebook.com/sharer/sharer.php?s=100&amp;p%5Burl%5D=https%3A%2F%2Fjavascript.info%2Farray-methods" rel="nofollow"></a></div><div class="article-tablet-foot__map"><a class="map" href="/tutorial/map" data-action="tutorial-map"><span class="map__text">Tutorial map</span></a></div></div></div><div class="banner-bottom-carbon"><div id="javascriptinfo_iconbar"></div></div><script src="//m.servedby-buysellads.com/monetization.custom.js" id="javascriptinfo_script" async></script><script>document.getElementById("javascriptinfo_script").onload=function(){_bsa.init("custom","CKYDEK3U","placement:javascriptinfo_iconbar",{target:"#javascriptinfo_iconbar",template:'\n <div class="iconBarFlex">\n <a href="##statlink##" class="iconBarLink" rel="sponsored noopener" target="_blank" title="##company## — ##tagline##">\n <div class="iconBarImage" style="background-color: ##backgroundColor##;">\n <img height="30" width="30" src="##image##" alt="##company## logo">\n </div>\n <div class="iconBarText">\n <div class="iconBarTagline">##companyTagline##</div>\n <div class="iconBarDescription">##description##</div>\n </div>\n </a>\n <a href="##ad_via_link##" class="iconBarVia" rel="sponsored noopener" target="_blank">ads via BuySellAds</a>\n </div>\n '})};</script><div class="comments formatted" id="comments"><div class="comments__header"><h2 class="comments__header-title"><a href="#comments" name="comments">Comments</a></h2><div class="comments__read-before"><span class="comments__read-before-link">read this before commenting…</span><div class="comments__read-before-popup"><div class="comments__read-before-popup-i"><ul><li>If you have suggestions what to improve - please <a href="https://github.com/javascript-tutorial/en.javascript.info/issues/new">submit a GitHub issue</a> or a pull request instead of commenting.</li><li>If you can't understand something in the article – please elaborate.</li><li>To insert few words of code, use the <code>&lt;code&gt;</code> tag, for several lines – wrap them in <code>&lt;pre&gt;</code> tag, for more than 10 lines – use a sandbox (<a href='https://plnkr.co/edit/?p=preview'>plnkr</a>, <a href='https://jsbin.com'>jsbin</a>, <a href='http://codepen.io'>codepen</a>…)</li></ul></div></div></div></div><div id="disqus_thread"></div><script>var disqus_config = function() { if (!this.page) this.page = {}; Object.assign(this.page, {"url":"https:\/\/javascript.info\/array-methods","identifier":"\/array-methods"}); };</script><script>var disqus_shortname = "javascriptinfo";</script><script>var disqus_enabled = true;</script></div></script></main></div><div class="sidebar page__sidebar sidebar sidebar_sticky-footer"><button class="sidebar__toggle" data-sidebar-toggle></button><a class="map" href="/tutorial/map" data-action="tutorial-map" data-tooltip="Tutorial map"></a><div class="sidebar__inner"><div class="sidebar__content"><div class="sidebar__section"><h4 class="sidebar__section-title">Chapter</h4><nav class="sidebar__navigation"><ul class="sidebar__navigation-links"><li class="sidebar__navigation-link"><a class="sidebar__link" href="/data-types">Data types</a></li></ul></nav></div><div class="sidebar__section"><h4 class="sidebar__section-title">Lesson navigation</h4><nav class="sidebar__navigation"><ul class="sidebar__navigation-links"><li class="sidebar__navigation-link"><a class="sidebar__link" href="#add-remove-items">Add/remove items</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#iterate-foreach">Iterate: forEach</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#searching-in-array">Searching in array</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#transform-an-array">Transform an array</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#array-isarray">Array.isArray</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#most-methods-support-thisarg">Most methods support “thisArg”</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#summary">Summary</a></li></ul></nav></div><div class="sidebar__section"><nav class="sidebar__navigation"><ul class="sidebar__navigation-links"><li class="sidebar__navigation-link"><a class="sidebar__link" href="#tasks">Tasks (13)</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#comments">Comments</a></li></ul></nav></div><div class="sidebar__section"><div class="sidebar__section-title">Share</div><a class="share share_tw sidebar__share" href="https://twitter.com/share?url=https%3A%2F%2Fjavascript.info%2Farray-methods" rel="nofollow"></a><a class="share share_fb sidebar__share" href="https://www.facebook.com/sharer/sharer.php?s=100&amp;p[url]=https%3A%2F%2Fjavascript.info%2Farray-methods" rel="nofollow"></a></div><div class="sidebar__section"><a class="sidebar__link" href="https://github.com/javascript-tutorial/en.javascript.info/blob/master/1-js/05-data-types/05-array-methods" rel="nofollow">Edit on GitHub</a></div><div class="sidebar__section" id="sponsorBar"><div class="sidebar__section-title" id="sponsorBarTitle"></div><div id="sponsorBarContent"></div></div><script>window.initSponsorBar()</script></div></div></div></div></div><div class="page-footer"><ul class="page-footer__list"><li class="page-footer__item page-footer__item_copy">©&nbsp;2007—2025&nbsp; Ilya Kantor</li><li class="page-footer__item page-footer__item_about"><a class="page-footer__link" href="/about">about the project</a></li><li class="page-footer__item page-footer__item_contact"><a class="page-footer__link" href="/about#contact-us">contact us</a></li><li class="page-footer__item page-footer__item_terms"><a class="page-footer__link" href="/terms">terms of usage</a></li><li class="page-footer__item page-footer__item_privacy"><a class="page-footer__link" href="/privacy">privacy policy</a></li></ul></div></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10