CINXE.COM
<!DOCTYPE html><html lang="ja" data-theme-enabled="1"><head><script>window.currentUser = null;</script><script>window.shopCurrency = "EUR";</script><script>window.localCurrency = "JPY";</script><script>window.countryCode = "jp";</script><script>window.rateShopTo = {"JPY":162.27920234065203,"EUR":1,"USD":1.0784426856242513,"AMD":422.9305849580972};</script><title itemprop="name">配列のメソッド</title><link href="/pack/styles.67c491fae690f87b1f9f.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"><!-- chrome autotranslate is enabled only for "en" main version--><meta name="google" content="notranslate"><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://ja.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://ja.javascript.info/img/site_preview_en_512x512.png"><meta property="og:title" content="配列のメソッド"><meta property="og:image" content="https://ja.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="配列のメソッド"><meta name="twitter:site" content="@iliakan"><meta name="twitter:creator" content="@iliakan"><meta name="twitter:image" content="https://ja.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.9d0331bb294e70c56db9.js"></script><script src="/pack/head.3c336e1939c677aeed65.js" defer></script><meta property="og:title" content="配列のメソッド"><meta property="og:type" content="article"><script src="/pack/tutorial.2da25d21c2b13cad643f.js" defer></script><script src="/pack/footer.4d7a62439a3935a4745e.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">申し訳ありません、Internet Explorer はサポートしていないため新しいブラウザを使用してください。</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 = "ja";</script><div class="sitetoolbar__content"><div class="sitetoolbar__lang-switcher"><button class="sitetoolbar__dropdown-button" data-dropdown-toggler>JA</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"><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 supported-langs__item_current"><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">私たちはこのオープンソースプロジェクトを世界中の人々に提供したいと考えています。このチュートリアルの内容をあなたが知っている言語に<a href="https://javascript.info/translate#help" rel="noopener noreferrer" target="_blank">翻訳するのを手伝って</a>ください。</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">購入する</span>EPUB/PDF</a></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="チュートリアル内を検索" required="required" type="text"/></div><button class="sitetoolbar__find" type="submit">検索</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="チュートリアル内を検索" required="required"/><button class="tablet-menu-search__button" type="submit" name="type" value="articles">検索</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">チュートリアルマップ</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">シェア</span><a class="share share_tw" href="https://twitter.com/share?url=https%3A%2F%2Fja.javascript.info%2Farray-methods" rel="nofollow"></a><a class="share share_fb" href="https://www.facebook.com/sharer/sharer.php?s=100&p%5Burl%5D=https%3A%2F%2Fja.javascript.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">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" selected>日本語</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="92" data-tooltip="レッスン 41 of 92"></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">チュートリアル</span></a></li><li class="breadcrumbs__item" id="breadcrumb-1"><a class="breadcrumbs__link" href="/js"><span>JavaScript 言語</span></a></li><li class="breadcrumbs__item" id="breadcrumb-2"><a class="breadcrumbs__link" href="/data-types"><span>データ型</span></a></li><script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"チュートリアル","item":"https://ja.javascript.info/"},{"@type":"ListItem","position":2,"name":"JavaScript 言語","item":"https://ja.javascript.info/js"},{"@type":"ListItem","position":3,"name":"データ型","item":"https://ja.javascript.info/data-types"}]}</script></ol><div class="updated-at" data-tooltip="最終更新日2024年9月24日"><div class="updated-at__content">2024年9月24日</div></div></div><h1 class="main__header-title">配列のメソッド</h1></div></header><div class="content"><article class="formatted" itemscope itemtype="http://schema.org/TechArticle"><meta itemprop="name" content="配列のメソッド"><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>配列は多くのメソッドを提供します。分かりやすくするために、このチャプターではグループに分けて説明します。</p> <h2><a class="main__anchor" name="ref-551" href="#ref-551">アイテムの追加/削除</a></h2><p>私たちは既に先頭または末尾にアイテムを追加/削除するメソッドを知っています:</p> <ul> <li><code>push(...items)</code> は <code>items</code> を末尾に追加します。</li> <li><code>pop()</code> は末尾の要素を削除し、それを返します。</li> <li><code>shift()</code> は先頭の要素を削除し、それを返します。</li> <li><code>unshift(...items)</code> はアイテムを先頭に追加します。</li> </ul> <p>他にもいくつかあります。</p> <h3><a class="main__anchor" name="ref-552" href="#ref-552">splice</a></h3><p>配列から要素を削除する方法はどのようになるでしょう?</p> <p>配列はオブジェクトなので、 <code>delete</code> を試すことができます:</p> <div id="7qgktrjbwg" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 = ["I", "go", "home"]; delete arr[1]; // "go" を削除 alert( arr[1] ); // undefined // now arr = ["I", , "home"]; alert( arr.length ); // 3</code></pre> </div> </div> </div><p>要素は削除されましたが、配列は依然として3つの要素を持っており、<code>arr.length == 3</code> となります。</p> <p>これは自然なことです。なぜなら、 <code>delete obj.key</code> は <code>key</code> で値を削除するためのものです。それがすべてであり、オブジェクトでは問題ありません。しかし、通常配列では残りの要素が移動し、解放された場所を埋めたいです。今より短い配列になることを期待しています。</p> <p>なので、特別なメソッドを使用する必要があります。</p> <p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">arr.splice(str)</a> メソッドは、配列用のスイス製アーミーナイフです。それは何でもすることができます: 追加、削除、また要素の挿入も。</p> <p>構文:</p> <div id="fzavxj3kqx" 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(index[, deleteCount, elem1, ..., elemN])</code></pre> </div> </div> </div><p>位置 <code>index</code> から始まります。 <code>deleteCount</code> の要素を削除した後、その場所に <code>elem1, ..., elemN</code> を挿入します。このメソッドは削除した要素の配列を返します。</p> <p>このメソッドは例で簡単に把握できます。</p> <p>削除してみましょう:</p> <div id="zgu1qbph89" data-trusted="1" class="code-example" data-highlight="[{"start":2,"end":2}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 = ["I", "study", "JavaScript"]; arr.splice(1, 1); // インデックス 1 から 1 要素を削除 alert( arr ); // ["I", "JavaScript"]</code></pre> </div> </div> </div><p>簡単ですね。インデックス <code>1</code> から始まり、<code>1</code> つ要素を削除します。</p> <p>次の例では、3つの要素を削除し、他の2つの要素でそれらを置き換えます:</p> <div id="zgqfizjd89" data-trusted="1" class="code-example" data-highlight="[{"start":5,"cols":[{"start":20,"end":36}]},{"start":0,"cols":[{"start":11,"end":38}]}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 = ["I", "study", "JavaScript", "right", "now"]; // 最初の 3 要素を削除し、別のものに置換 arr.splice(0, 3, "Let's", "dance"); alert( arr ) // 今は ["Let's", "dance", "right", "now"]</code></pre> </div> </div> </div><p>ここで、<code>splice</code> が削除された要素の配列を返していることを見ることができます:</p> <div id="m7qcwxfh86" data-trusted="1" class="code-example" data-highlight="[{"start":0,"cols":[{"start":11,"end":24}]}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 = ["I", "study", "JavaScript", "right", "now"]; // 最初の 2 要素を削除 let removed = arr.splice(0, 2); alert( removed ); // "I", "study" <-- 削除された要素の配列</code></pre> </div> </div> </div><p><code>splice</code> メソッドは削除せずに挿入することも可能です。そのためには、<code>deleteCount</code> に <code>0</code> をセットします:</p> <div id="yphqjbycn7" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 = ["I", "study", "JavaScript"]; // インデックス 2 から // 削除 0 // その後 "complex" と "language" を挿入 arr.splice(2, 0, "complex", "language"); alert( arr ); // "I", "study", "complex", "language", "JavaScript"</code></pre> </div> </div> </div><div class="important important_smart"> <div class="important__header"><span class="important__type">負のインデックスも許容します</span></div> <div class="important__content"><p>上記や他の配列のメソッドでは、負のインデックスが許容されます。それらは配列の末尾からの位置を指定します。:</p> <div id="ynoehluarq" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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]; // インデックス -1 (末尾から1つ前) から // 削除 0 要素, // その後 3 と 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="ref-553" href="#ref-553">slice</a></h3><p>メソッド <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">arr.slice</a> は似たように見える <code>arr.splice</code> よりもはるかに単純です。</p> <p>構文:</p> <div id="6wnji4d6wb" 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>開始インデックス <code>"start"</code> から <code>"end"</code> (<code>"end"</code> は含みません)のすべてのアイテムをコピーした新しい配列を返します。<code>start</code> と <code>end</code> はともに負値になることができます。そのときは、配列の末尾からの位置が想定されます。</p> <p><code>str.slice</code> のように動作しますが、部分文字列の代わりに部分配列を作ります。</p> <p>例:</p> <div id="bcjjhwh3qy" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 = ["t", "e", "s", "t"]; alert( arr.slice(1, 3) ); // e,s (1 から 3 をコピー) alert( arr.slice(-2) ); // s,t (-2 から末尾まで)</code></pre> </div> </div> </div><p>引数なし <code>arr.slice()</code> でも呼び出すことができ、これは <code>arr</code> のコピーを生成します。これは、オリジナルの配列に影響を与えない形でさらに変換するためのためのコピーを取得するのによく使用されます。</p> <h3><a class="main__anchor" name="ref-554" href="#ref-554">concat</a></h3><p>メソッド <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/concat">arr.concat</a> は配列を他の配列またはアイテムと結合します。</p> <p>構文:</p> <div id="svs3m0v472" 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>任意の数の引数(配列または値)を許容します。</p> <p>結果は <code>arr</code>, 次に <code>arg1</code>, <code>arg2</code> などのアイテムを含む新しい配列を返します。</p> <p>もし、引数が配列、もしくは <code>Symbol.isConcatSpreadable</code> プロパティを持っている場合、その全ての要素がコピーされます。そうでない場合、引数自体がコピーされます。</p> <p>例:</p> <div id="p41qictqfo" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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]; // arr と [3,4] をマージ alert( arr.concat([3, 4])); // 1,2,3,4 // arr と [3,4] と [5,6] をマージ alert( arr.concat([3, 4], [5, 6])); // 1,2,3,4,5,6 // arr と [3,4] をマージ後, 5 と 6 を追加 alert( arr.concat([3, 4], 5, 6)); // 1,2,3,4,5,6</code></pre> </div> </div> </div><p>通常は、配列から要素をコピーするだけです。それ以外のオブジェクトでは、配列のように見えたとしても、全体として追加されます:</p> <div id="bc0u9886vq" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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: "something", length: 1 }; alert( arr.concat(arrayLike) ); // 1,2,[object Object]</code></pre> </div> </div> </div><p>…しかし、もし配列のようなオブジェクトが <code>Symbol.isConcatSpreadable</code> プロパティを持つ場合、<code>concat</code> は配列として扱います。つまり、代わりにその要素が追加されます:</p> <div id="agdt3o9btd" data-trusted="1" class="code-example" data-highlight="[{"start":5,"end":5}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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: "something", 1: "else", [Symbol.isConcatSpreadable]: true, length: 2 }; alert( arr.concat(arrayLike) ); // 1,2,something,else</code></pre> </div> </div> </div><h2><a class="main__anchor" name="ref-555" href="#ref-555">イテレート/反復: forEach</a></h2><p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">arr.forEach</a> メソッドは配列の全要素に対して関数を実行することができます。</p> <p>構文:</p> <div id="1mc93a8u6b" 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) { // ... item に対して何か処理をする });</code></pre> </div> </div> </div><p>例えば、これは配列の各要素を表示します:</p> <div id="2usvxp4yjb" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 を呼び出す ["Bilbo", "Gandalf", "Nazgul"].forEach(alert);</code></pre> </div> </div> </div><p>そしてこのコードは、ターゲットとなる配列内の位置についてより細かいです。</p> <div id="19pj8d5xlv" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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>["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => { alert(`${item} is at index ${index} in ${array}`); });</code></pre> </div> </div> </div><p>関数の結果(もし何かを返す場合)は捨てられ、無視されます。</p> <h2><a class="main__anchor" name="ref-556" href="#ref-556">配列での検索</a></h2><p>これらは、配列で何かを探すためのメソッドです。</p> <h3><a class="main__anchor" name="ref-557" href="#ref-557">indexOf/lastIndexOf and includes</a></h3><p>メソッド <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf">arr.indexOf</a>, <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf">arr.lastIndexOf</a> と <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/includes">arr.includes</a> は文字列の場合と同じ構文を持ち、基本的に同じことを行いますが、文字の代わりにアイテムを操作します:</p> <ul> <li><code>arr.indexOf(item, from)</code> はインデックス <code>from</code> から <code>item</code> を探し、見つかった場所のインデックスを返します。そうでない場合は <code>-1</code> になります。</li> <li><code>arr.lastIndexOf(item, from)</code> は同じですが、右から左に見ていきます。</li> <li><code>arr.includes(item, from)</code> はインデックス <code>from</code> から <code>item</code> を探し、見つかった場合、<code>true</code> を返します。</li> </ul> <p>例:</p> <div id="yo8nz17rw" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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>メソッドは <code>===</code> 比較を使うことに留意してください。そのため、もしも <code>false</code> を探す場合、ゼロではなく、正確な <code>false</code> を見つけようとします。</p> <p>もしも含んでいるかをチェックしたいが、正確なインデックスは不要なときは、<code>arr.includes</code> が好ましいです。</p> <p>また、<code>includes</code> の非常に小さな違いは、<code>indexOf/lastIndexOf</code> と違い、<code>NaN</code> を正しく処理することができます:</p> <div id="p6y3kj85wm" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 (0 になるべきですが, === 等値は NaN では機能しません) alert( arr.includes(NaN) );// true (正しい)</code></pre> </div> </div> </div><h3><a class="main__anchor" name="ref-558" href="#ref-558">find と findIndex</a></h3><p>オブジェクトの配列を持っていることを想像してください。特定条件を持つオブジェクトをどのようにして見つけますか?</p> <p>ここで <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/find">arr.find</a> メソッドが便利です。</p> <p>構文はこうです:</p> <div id="nqx6nd143e" 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) { // true が返却されると、item が返却され、イテレーションは停止します // 偽の場合は undefined です });</code></pre> </div> </div> </div><p>関数は配列の要素毎に繰り返し呼ばれます:</p> <ul> <li><code>item</code> は要素です。</li> <li><code>index</code> はインデックスです。</li> <li><code>array</code> は配列自身です。</li> </ul> <p>もし <code>true</code> を返すと、検索が止まり、<code>item</code> が返却されます。見つからない場合は <code>undefined</code> になります。</p> <p>例えば、ユーザの配列を持っており、それぞれフィールド <code>id</code> と <code>name</code> を持っているとします。<code>id == 1</code> のものを見つけましょう:</p> <div id="3gdelna7sq" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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: "John"}, {id: 2, name: "Pete"}, {id: 3, name: "Mary"} ]; let user = users.find(item => item.id == 1); alert(user.name); // John</code></pre> </div> </div> </div><p>現実の世界では、オブジェクトの配列は一般的なことです。なので、 <code>find</code> メソッドは非常に役立ちます。</p> <p>例の中では1つの引数、関数 <code>item => item.id == 1</code> で <code>find</code> を行っている点に注意してください。<code>find</code> の他のパラメータは殆ど使われません。</p> <p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex">arr.findIndex</a> メソッドは基本的に同じです。が、要素自体ではなく要素が見つかったインデックスを返します。</p> <h3><a class="main__anchor" name="ref-559" href="#ref-559">filter</a></h3><p><code>find</code> メソッドは、関数が <code>true</code> を返すようにする単一の(最初の)要素を探します。</p> <p>もし複数になる可能性がある場合、<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">arr.filter(fn)</a> を使います。</p> <p>構文は大体 <code>find</code> と同じですが、<code>filter</code> はマッチしたすべて要素の配列を返します:</p> <div id="lq3pnlapus" 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) { // true の場合、item は results にプッシュされ、イテレーションは継続します // 何も見つからない場合は、空配列を返します });</code></pre> </div> </div> </div><p>例:</p> <div id="ux3x4rtbx4" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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: "John"}, {id: 2, name: "Pete"}, {id: 3, name: "Mary"} ]; // 最初の2人のユーザの配列を返します let someUsers = users.filter(item => item.id < 3); alert(someUsers.length); // 2</code></pre> </div> </div> </div><h2><a class="main__anchor" name="ref-560" href="#ref-560">配列を変換する</a></h2><p>このセクションでは、配列を変換または並び替える方法について説明します。</p> <h3><a class="main__anchor" name="ref-561" href="#ref-561">map</a></h3><p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map">arr.map</a> メソッドは最も便利なものの1つで、よく使われます。</p> <p>これは、配列の各要素に対して関数を呼び出し、結果の配列を返します。</p> <p>構文は次の通りです:</p> <div id="7mvywlcai3" 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) { // item の代わりに新しい値を返します })</code></pre> </div> </div> </div><p>例えば、ここでは各要素をその長さに変換します:</p> <div id="2rtw4fy2ps" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length) alert(lengths); // 5,7,6</code></pre> </div> </div> </div><h3><a class="main__anchor" name="ref-562" href="#ref-562">sort(fn)</a></h3><p>メソッド <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/sort">arr.sort</a> は配列を <em>決まった位置に</em> ソートし、要素の順番を変更します。</p> <p>これもソートされた配列を返しますが、<code>arr</code> 自身が変更されるので、返却値は通常無視されます。</p> <p>例:</p> <div id="xph4j2svw7" data-trusted="1" class="code-example" data-highlight="[{"start":5,"cols":[{"start":18,"end":26}]}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 の内容を並べ替え(てそれを返します) arr.sort(); alert( arr ); // 1, 15, 2</code></pre> </div> </div> </div><p>出力結果が何か不自然であることに気づきましたか?</p> <p>並び順が <code>1, 15, 2</code> となりました。正しくないようです。しかしなぜでしょう?</p> <p><strong>アイテムは、デフォルトでは文字列としてソートされます。</strong></p> <p>文字通り、すべての要素は文字列に変換され、比較されます。なので、辞書編集順序が適用され、実際には <code>"2" > "15"</code> となります。</p> <p>私たち独自のソート順を使うためには、<code>arr.sort()</code> の引数として、2つの引数をもつ関数を指定する必要があります。</p> <p>関数はこのように動作する必要があります:</p> <div id="69woz97ozi" 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 > b) return 1; if (a == b) return 0; if (a < b) return -1; }</code></pre> </div> </div> </div><p>例:</p> <div id="wwik9ulzpi" data-trusted="1" class="code-example" data-highlight="[{"start":10,"cols":[{"start":16,"end":24}]},{"start":8,"end":8}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 > b) return 1; if (a == b) return 0; if (a < b) return -1; } let arr = [ 1, 2, 15 ]; arr.sort(compareNumeric); alert(arr); // 1, 2, 15</code></pre> </div> </div> </div><p>これで意図したとおりに動作します。</p> <p>立ち止まって何が起きているのか考えてみましょう。<code>arr</code> は何でも配列にすることができます。それは数値や文字列、html要素やその他何でも含まれる可能性があります。私たちは <em>何かの</em> セットを持っています。それらをソートするためには、要素を比較する方法を知っている <em>順序付け関数</em> が必要です。 デフォルトは文字列です。</p> <p><code>arr.sort(fn)</code> メソッドは組み込みでソートアルゴリズムの実装を持っています。私たちはそれが正確にどのように動作するかについては気にする必要はありません (殆どの場合、最適化された<a href="https://en.wikipedia.org/wiki/Quicksort">クイックソート</a> です)。配列の要素を見ていき、提供された関数を使ってその要素を比較し、並べ替えます。私たちに必要なのは、比較を行う <code>fn</code> を提供することだけです。</p> <p>ところで、もしどの要素が比較されているかを知りたいとき、<code>alert</code> をしても問題ありません:</p> <div id="hsjwnszy0d" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 + " <> " + b ); return a - b; });</code></pre> </div> </div> </div><p>アルゴリズムは処理の中で複数回要素を比較しますが、できるだけ回数を少なくしようとします。</p> <div class="important important_smart"> <div class="important__header"><span class="important__type">比較関数は任意の数を返すことがあります</span></div> <div class="important__content"><p>実際には、比較関数は正の数を「より大きい」、負の数を「より小さい」として返せば十分です。</p> <p>より短い関数で書くことができます:</p> <div id="ymwwxc1lmh" data-trusted="1" class="code-example" data-highlight="[{"start":4,"cols":[{"start":16,"end":24}]}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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">ベストなアロー関数</span></div> <div class="important__content"><p><a href="/arrow-functions-basics">アロー関数</a> を覚えていますか? すっきりしたソートを書くために使えます。:</p> <div id="m9pbhn7z0y" 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) => a - b );</code></pre> </div> </div> </div><p>これは、他の上で書いているより長いバージョンとまったく同じように動作します。</p> </div></div> <div class="important important_smart"> <div class="important__header"><span class="important__type">文字列には <code>localeCompare</code> を使用します</span></div> <div class="important__content"><p><a href="/string#correct-comparisons">strings</a>の比較アルゴリズムを思い出してください。デフォルトではコードで文字比較を行います。</p> <p>多くのアルファベットでは、<code>Ö</code> などの文字のソートを正しく行うためのメソッド <code>str.localeCompare</code> を使用するのがよいです。</p> <p>例えば、ドイツ語でいくつかの国をソートしてみましょう:</p> <div id="j6t8jzcmwh" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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) => a > b ? 1 : -1) ); // Andorra, Vietnam, Österreich (間違い) alert( countries.sort( (a, b) => a.localeCompare(b) ) ); // Andorra,Österreich,Vietnam (正しい!)</code></pre> </div> </div> </div></div></div> <h3><a class="main__anchor" name="ref-563" href="#ref-563">reverse</a></h3><p>メソッド <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse">arr.reverse</a> は <code>arr</code> 内の要素の順序を逆転させます。</p> <p>例:</p> <div id="thmyzdbvb8" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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>また、反転後に配列 <code>arr</code> を返します。</p> <h3><a class="main__anchor" name="ref-564" href="#ref-564">split と join</a></h3><p>ここでは現実世界でのシチュエーションを考えます。私たちはメッセージングアプリを書いており、利用者はカンマ区切りで受信者のリスト(<code>John, Pete, Mary</code>)を入力します。しかし、我々にとっては、1つの文字列よりも名前の配列の方がはるかに扱いやすいです。それを得る方法は?</p> <p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/split">str.split(delim)</a> メソッドは、まさにそれをします。与えられた区切り文字 <code>delim</code> で文字列を配列に分割します。</p> <p>下の例では、スペースに続くカンマで分割しています:</p> <div id="pjtb3po6b6" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 (と他の名前) }</code></pre> </div> </div> </div><p><code>split</code> メソッドは任意の2つ目の数値の引数を持っています。それは配列の長さの制限です。もしこれが指定された場合、余分な要素は無視されます。実際にはほとんど使われませんが。:</p> <div id="9vw0fugxdq" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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">文字への分割</span></div> <div class="important__content"><p><code>s</code> を空にして <code>split(s)</code> を呼び出すと、文字列を文字の配列に分割します:</p> <div id="725r2avq8g" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 = "test"; alert( str.split('') ); // t,e,s,t</code></pre> </div> </div> </div></div></div> <p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/join">arr.join(str)</a> は <code>split</code> と逆を行います。<code>arr</code> のアイテムを <code>str</code> で繋いだ文字列を作ります。</p> <p>例:</p> <div id="oppg2xl1d8" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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(';'); alert( str ); // Bilbo;Gandalf;Nazgul</code></pre> </div> </div> </div><h3><a class="main__anchor" name="ref-565" href="#ref-565">reduce/reduceRight</a></h3><p>配列に対して繰り返し処理が必要なときは、<code>forEach</code>, <code>for</code> あるいは <code>for..of</code> を使うことができます。</p> <p>各要素のデータを反復して返す必要があるときには、<code>map</code>を使うことができます。</p> <p>メソッド <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce">arr.reduce</a> と <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight">arr.reduceRight</a> もまたその種類に属しますが、少し複雑です。それらは、配列に基づいて単一の値を計算するために使用されます。</p> <p>構文:</p> <div id="rsyw7pjk5h" 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, arr) { // ... }, initial);</code></pre> </div> </div> </div><p>関数は各要素に順番に適用され、その結果を次の呼び出しに “引き継ぎ” ます:</p> <p>引数:</p> <ul> <li><code>accumulator</code> – 前の関数呼び出しの結果で、初回は <code>initial</code> と等価です(<code>initial</code> が指定されている場合)</li> <li><code>item</code> – 現在の配列の項目です。</li> <li><code>index</code> – 位置です。</li> <li><code>arr</code> – 配列です。</li> </ul> <p>関数が適用されると、前の関数呼び出しの結果が、次の関数呼び出しの最初の引数として渡されます。</p> <p>したがって、最初の引数は基本的に、以前のすべての実行の結合結果を格納するアキュムレータです。そして、最後にそれは <code>reduce</code> の結果になります。</p> <p>複雑に見えますか?</p> <p>これを掴むための最も簡単な方法は、例を見る、です。</p> <p>ここでは、1行で配列の合計を取得します。</p> <div id="h5mkey5lmv" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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) => sum + current, 0); alert(result); // 15</code></pre> </div> </div> </div><p>ここでは、2つの引数だけを使用する <code>reduce</code> の最も一般的なパターンを使用しました。</p> <p>何が起きているか、詳細を見てみましょう。</p> <ol> <li>最初の実行で <code>sum</code> は <code>initial</code> 値(<code>reduce</code> の最後の引数)であり、 <code>0</code> です。そして、<code>current</code> は最初の配列要素で <code>1</code> になります。従って、結果は <code>1</code> です。</li> <li>2回目の実行では、<code>sum = 1</code> で、2つ目の配列要素(<code>2</code>)をそれに足して返します。</li> <li>3回目の実行では、<code>sum = 3</code> で、それに1つ要素を足します。それが続きます。</li> </ol> <p>計算のフロー:</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>また、次のテーブルでは、各行は次の配列要素の関数呼び出しを表しています。</p> <table> <thead> <tr> <th></th> <th><code>sum</code></th> <th><code>current</code></th> <th><code>result</code></th> </tr> </thead> <tbody> <tr> <td>最初の呼び出し</td> <td><code>0</code></td> <td><code>1</code></td> <td><code>1</code></td> </tr> <tr> <td>2回目の呼び出し</td> <td><code>1</code></td> <td><code>2</code></td> <td><code>3</code></td> </tr> <tr> <td>3回目の呼び出し</td> <td><code>3</code></td> <td><code>3</code></td> <td><code>6</code></td> </tr> <tr> <td>4回目の呼び出し</td> <td><code>6</code></td> <td><code>4</code></td> <td><code>10</code></td> </tr> <tr> <td>5回目の呼び出し</td> <td><code>10</code></td> <td><code>5</code></td> <td><code>15</code></td> </tr> </tbody> </table> <p>これらから分かるように、前の呼び出しの結果は次の実行のときの最初の引数になっています。</p> <p>また、 initial 値を省略することもできます。:</p> <div id="zib1l8fnlu" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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]; // reduce から初期値を削除する(最後の 0 を削除) let result = arr.reduce((sum, current) => sum + current); alert( result ); // 15</code></pre> </div> </div> </div><p>結果は同じです。なぜなら、初期値が指定されていない場合、<code>reduce</code> は配列の最初の要素を初期値とみなし、2つ目の要素から繰り返し処理を始めるためです。</p> <p>計算テーブルは、上と同じで最初の行を引いたものです。</p> <p>しかし、このような利用は極度の注意を要求します。もし配列が空の場合、初期値がない状態で <code>reduce</code> を呼び出すと、エラーが発生してしまいます。</p> <p>例:</p> <div id="3evzcq4mtt" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 はエラーです // 初期値が存在する場合、reduce は空の arr に対しそれを返します。 arr.reduce((sum, current) => sum + current);</code></pre> </div> </div> </div><p>従って、常に初期値を指定することをおすすめします。</p> <p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight">arr.reduceRight</a> メソッドも同じをことを行いますが、右から左に実行します。</p> <h2><a class="main__anchor" name="ref-566" href="#ref-566">Array.isArray</a></h2><p>配列は別の言語の型を形成しません。 それらはオブジェクトに基づいています。</p> <p>なので <code>typeof</code> では、通常のオブジェクトと配列を区別するのには助けになりません:</p> <div id="1v0bj4yo4q" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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(同じ)</code></pre> </div> </div> </div><p>…しかし、配列は頻繁に使用されるため、そのための特別なメソッド <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray">Array.isArray(value)</a> があります。これは、<code>value</code> が配列のときに <code>true</code> を、そうでない場合には <code>false</code> を返します。</p> <div id="pn9chd12je" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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="ref-567" href="#ref-567">ほとんどのメソッドは “thisArg” をサポートします</a></h2><p><code>find</code>、<code>filter</code>、<code>map</code> のような関数を呼び出すほとんどの配列メソッドは、<code>sort</code> の例外を除いて、任意の追加パラメータ <code>thisArg</code> を受け取ります。</p> <p>これは殆ど使われないため、このパラメータは上のセクションでは説明されていません。しかし、完全性のためにはそれをカバーする必要があります。</p> <p>それらのメソッドの完全な構文です:</p> <div id="c21fmuxlyz" 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 はオプションの最後の引数です</code></pre> </div> </div> </div><p><code>thisArg</code> パラメータの値は <code>func</code> での <code>this</code> になります。</p> <p>例えば、ここでは filter で <code>army</code> オブジェクトのメソッドを使用し、<code>thisArg</code> はそのコンテキストを渡します。:</p> <div id="wk5bkchip7" data-trusted="1" class="code-example" data-highlight="[{"start":15,"end":16}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 >= this.minAge && user.age < this.maxAge; } }; let users = [ {age: 16}, {age: 20}, {age: 23}, {age: 30} ]; // army.canJoin が 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>もし上の例で <code>users.filter(army.canJoin)</code> としていた場合、<code>army.canJoin</code> はスタンドアローンの関数として呼び出されるため、<code>this=undefined</code> であり、即時エラーになります。</p> <p>呼び出し <code>users.filter(army.canJoin, army)</code> は <code>users.filter(user => army.canJoin(user))</code> に置き換え可能であり、同じことをします。多くの人にとってより理解しやすいので、後者の方がよく利用されます。</p> <h2><a class="main__anchor" name="ref-568" href="#ref-568">サマリ</a></h2><p>配列メソッドの チートシート です:</p> <ul> <li> <p>要素の追加/削除をする場合:</p> <ul> <li><code>push(...items)</code> – アイテムを末尾に追加します,</li> <li><code>pop()</code> – 末尾からアイテムを抽出します,</li> <li><code>shift()</code> – 先頭からアイテムを抽出します,</li> <li><code>unshift(...items)</code> – 先頭にアイテムを追加します.</li> <li><code>splice(pos, deleteCount, ...items)</code> – インデックス <code>pos</code> から <code>deleteCount</code> 数要素を削除し <code>items</code> を挿入します。</li> <li><code>slice(start, end)</code> – 新しい配列を作り、<code>start</code> から <code>end</code> まで(endは含まない) の要素をコピーします。</li> <li><code>concat(...items)</code> – 新しい配列を返します: 現在のものすべてをコピーし、<code>items</code> を追加します。<code>items</code> のいずれかが配列の場合、その要素が取得されます。</li> </ul> </li> <li> <p>要素を検索する場合:</p> <ul> <li><code>indexOf/lastIndexOf(item, pos)</code> – 位置 <code>pos</code> から始めて <code>item</code> を探します。 インデックス、または見つからなかった場合は <code>-1</code> を返します。</li> <li><code>includes(value)</code> – 配列が <code>value</code> を持っている場合 <code>true</code> を返します。そうでなければ <code>false</code> です。</li> <li><code>find/filter(func)</code> – 関数を介して要素をフィルタリングし、<code>true</code> を返す最初の/すべての値を返します。</li> <li><code>findIndex</code> は <code>find</code> のようですが、値の代わりにインデックスを返します。</li> </ul> </li> <li> <p>要素を反復処理するには:</p> <ul> <li><code>forEach(func)</code> – すべての要素に対して <code>func</code>を呼び出し、何も返しません。</li> </ul> </li> <li> <p>配列を変換するには:</p> <ul> <li><code>map(func)</code> – すべての要素に対して <code>func</code> を呼び出した結果から新しい配列を作成します。</li> <li><code>sort(func)</code> – 配列を適切な位置でソートし、それを返します。</li> <li><code>reverse()</code> – 配列を反転してそれを返します。</li> <li><code>split/join</code> – 文字列を配列に変換したり、戻します。</li> <li><code>reduce/reduceRight(func, initial)</code> – 各要素に対して <code>func</code>を呼び出し、呼び出しの間に中間結果を渡すことで配列全体の単一の値を計算します。</li> </ul> </li> <li> <p>さらに:</p> <ul> <li><code>Array.isArray(arr)</code> は <code>arr</code> が配列かどうかをチェックします。</li> </ul> </li> </ul> <p><code>sort</code>, <code>reverse</code> と <code>splice</code> メソッドは、配列自身を変更することに注意してください。</p> <p>これらのメソッドは最も使われるもので、ユースケースの99%をカバーしますが、他にもいくつかあります:</p> <ul> <li> <p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/some">arr.some(fn)</a>/<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/every">arr.every(fn)</a> は配列をチェックします。</p> <p>関数 <code>fn</code> は <code>map</code> と同じように配列の各要素で呼ばれます。もし どれか/すべて の結果が <code>true</code> であれば <code>true</code>, それ以外は <code>false</code> になります。</p> <p>これらのメソッドは <code>||</code> や <code>&&</code> 演算子のように振る舞います。もし <code>fn</code> が真の値を返す場合、<code>arr.some()</code> はすぐに <code>true</code> を返し、残りの項目に対するイテレーションを停止します。<code>fn</code> が偽の値を返す場合は、<code>arr.every()</code> はすぐに <code>false</code> を返し、同様に残りの項目のイテレーションは停止します。</p> <p><code>every</code> は配列を比較するのに使えます:</p> <div id="8d800gfaeu" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 && arr1.every((value, index) => value === arr2[index]); } alert( arraysEqual([1, 2], [1, 2])); // true</code></pre> </div> </div> </div></li> <li> <p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/fill">arr.fill(value, start, end)</a> – インデックス <code>start</code> から <code>end</code> まで <code>value</code> で配列を埋めます。</p> </li> <li> <p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin">arr.copyWithin(target, start, end)</a> – 位置 <code>start</code> から <code>end</code> までの要素を、<em>自身</em> の <code>target</code> の位置にコピーします (既存のものを上書きします)。</p> </li> <li> <p><a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flat">arr.flat(depth)</a>/<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap">arr.flatMap(fn)</a> は多次元配列からフラットな配列を生成します。</p> </li> </ul> <p>完全なリストは <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array">manual</a> を見てください。</p> <p>初めてみたとき、多くのメソッドがあり覚えるのがとても難しいように見えるかもしれません。しかし、実際にはそう見えるよりもはるかに簡単です。</p> <p>チートシートを見て、それらを認識してください。 それから、このチャプターのタスクで練習してください。そうすれば配列メソッドの経験を積むことができます。</p> <p>今後、配列で何かをする必要があるとき、どうやればいいか分からないときはいつでもここに来て、 チートシート を見て正しいメソッドを見つけてください。例はあなたが正しくそのメソッドを使うのに役立つでしょう。使っていると自然とそれらのメソッドを覚えていくでしょう。</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">タスク</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="#ref-569" name="ref-569">border-left-width を 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="タスクの重要度を表し、1 から 5 までです">重要性: 5</span></div><div class="task__content"><div class="task__formatted"><p>“my-short-string” のようなダッシュ区切りの言葉をキャメルケースの “myShortString” に変更する関数 <code>camelize(str)</code> を書いてください。</p> <p>つまり、すべてのダッシュを削除し、ダッシュの後の各言葉を大文字にします。</p> <p>例:</p> <div id="y8zoc29dx8" 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("background-color") == 'backgroundColor'; camelize("list-style-image") == 'listStyleImage'; camelize("-webkit-transition") == 'WebkitTransition';</code></pre> </div> </div> </div><p>P.S. ヒント: 文字列を配列に分割するために <code>split</code> を使い、それを変換し、<code>join</code> 結果を返してください。</p> <p><a href="https://plnkr.co/edit/LxTZppmPpVozKkCoaNGL?p=preview" target="_blank" data-plunk-id="LxTZppmPpVozKkCoaNGL">テストと一緒にサンドボックスを開く</a></p></div><button class="task__solution" type="button">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="o5n1nlrp4w" 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('-') // my-long-word -> ['my', 'long', 'word'] .map( (word, index) => index == 0 ? word : word[0].toUpperCase() + word.slice(1) ) // ['my', 'long', 'word'] -> ['my', 'Long', 'Word'] .join(''); // ['my', 'Long', 'Word'] -> myLongWord }</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/Cu2Cwgl6QRmGWOZFlN3b?p=preview" target="_blank" data-plunk-id="Cu2Cwgl6QRmGWOZFlN3b">サンドボックスでテストと一緒に解答を開く</a></p></div></div><button class="close-button task__answer-close" type="button" title="閉じる"></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="#ref-570" name="ref-570">範囲でフィルタする</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="タスクの重要度を表し、1 から 5 までです">重要性: 4</span></div><div class="task__content"><div class="task__formatted"><p>配列 <code>arr</code> を取得し、<code>a</code> と <code>b</code> の間で要素を探し、それらの配列を返す関数 <code>filterRange(arr, a, b)</code> を書いてください。</p> <p>この関数は配列を変更するべきではありません。新しい配列を返すべきです。</p> <p>例:</p> <div id="jubjwr52m1" 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 (マッチした値) alert( arr ); // 5,3,8,1 (修正されていない)</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/2jm2JE0g8UwhcvuO0oKV?p=preview" target="_blank" data-plunk-id="2jm2JE0g8UwhcvuO0oKV">テストと一緒にサンドボックスを開く</a></p></div><button class="task__solution" type="button">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="007eqblp4r" 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 filterRange(arr, a, b) { // added brackets around the expression for better readability return arr.filter(item => (a <= item && item <= b)); }</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/1tyL0t7FXq0OIpFJiOyo?p=preview" target="_blank" data-plunk-id="1tyL0t7FXq0OIpFJiOyo">サンドボックスでテストと一緒に解答を開く</a></p></div></div><button class="close-button task__answer-close" type="button" title="閉じる"></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="#ref-571" name="ref-571">インプレースで範囲をフィルタする</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="タスクの重要度を表し、1 から 5 までです">重要性: 4</span></div><div class="task__content"><div class="task__formatted"><p>配列 <code>arr</code> を取得し、<code>a</code> と <code>b</code> の間を除くすべての値をそこから削除する関数 <code>filterRangeInPlace(arr, a, b)</code> を書いてください。テストは <code>a ≤ arr[i] ≤ b</code> です。</p> <p>この関数は配列のみを修正するべきです。なにも返却するべきではありません。</p> <p>例:</p> <div id="szu422z2ig" 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); // 1 から 4 までの値以外を削除 alert( arr ); // [3, 1]</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/euRtwwBLyxWQzkvFlyxV?p=preview" target="_blank" data-plunk-id="euRtwwBLyxWQzkvFlyxV">テストと一緒にサンドボックスを開く</a></p></div><button class="task__solution" type="button">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="p9i1ji8jg7" 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 filterRangeInPlace(arr, a, b) { for (let i = 0; i < arr.length; i++) { let val = arr[i]; // remove if outside of the interval if (val < a || val > b) { arr.splice(i, 1); i--; } } }</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/tsV0sZrbHqLbpCUY6NSn?p=preview" target="_blank" data-plunk-id="tsV0sZrbHqLbpCUY6NSn">サンドボックスでテストと一緒に解答を開く</a></p></div></div><button class="close-button task__answer-close" type="button" title="閉じる"></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="#ref-572" name="ref-572">逆の順序でソートする</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="タスクの重要度を表し、1 から 5 までです">重要性: 4</span></div><div class="task__content"><div class="task__formatted"><div id="0tooaamizn" 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]; // ... 逆順でソートをするあなたのコード alert( arr ); // 8, 5, 2, 1, -10</code></pre> </div> </div> </div></div><button class="task__solution" type="button">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="febw925bgn" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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) => b - a); alert( arr );</code></pre> </div> </div> </div></div></div><button class="close-button task__answer-close" type="button" title="閉じる"></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="#ref-573" name="ref-573">配列のコピーとソート</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="タスクの重要度を表し、1 から 5 までです">重要性: 5</span></div><div class="task__content"><div class="task__formatted"><p>文字列の配列 <code>arr</code> を持っています。私たちはソートされたそのコピーを持ちたいですが、<code>arr</code> を修正はせずにキープしたいです。</p> <p>このようなコピーを返す関数 <code>copySorted(arr)</code> を作成してください。</p> <div id="8h94gpbfeu" 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 = ["HTML", "JavaScript", "CSS"]; 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">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><p>コピーを作りそれをソートするのに、 <code>slice()</code> を使うことができます。:</p> <div id="9amky644xh" data-trusted="1" class="code-example" data-highlight="[{"start":6,"end":6}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 = ["HTML", "JavaScript", "CSS"]; 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="閉じる"></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="#ref-574" name="ref-574">拡張可能な計算機を作る</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="タスクの重要度を表し、1 から 5 までです">重要性: 5</span></div><div class="task__content"><div class="task__formatted"><p>“拡張可能な” 計算機オブジェクトを作るコンストラクタ関数 <code>Calculator</code> を作りなさい。</p> <p>タスクは2つのパートから構成されます。</p> <ol> <li> <p>最初に フォーマット “数値 演算子 数値” (スペース区切り) で、<code>"1 + 2"</code> のような文字列を取り、結果を返すメソッド <code>calculate(str)</code> メソッドを実装します。それはプラス <code>+</code> と マイナス <code>-</code> を理解できるようにしてください。</p> <p>使い方の例:</p> <div id="guirrz4qg2" 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("3 + 7") ); // 10</code></pre> </div> </div> </div></li> <li> <p>次に、計算機に新しい操作を教えるメソッド <code>addOperator(name, func)</code> を追加します。操作 <code>name</code> と、それを実装する2つの引数を持つ関数 <code>func(a,b)</code> を取ります。</p> <p>例えば、乗算 <code>*</code>, 除算 <code>/</code> やべき乗 <code>**</code>:</p> <div id="hfvvgeeor1" 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("*", (a, b) => a * b); powerCalc.addMethod("/", (a, b) => a / b); powerCalc.addMethod("**", (a, b) => a ** b); let result = powerCalc.calculate("2 ** 3"); alert( result ); // 8</code></pre> </div> </div> </div></li> </ol> <ul> <li>このタスクではかっこや複雑な表現は不要です。</li> <li>数字と演算子は、正確に1つのスペースで区切られます。</li> <li>追加したい場合にエラー処理があるかもしれません。</li> </ul> <p><a href="https://plnkr.co/edit/gNrg5OOvPo8kx01i6P2o?p=preview" target="_blank" data-plunk-id="gNrg5OOvPo8kx01i6P2o">テストと一緒にサンドボックスを開く</a></p></div><button class="task__solution" type="button">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><ul> <li>メソッドの格納方法に注意してください。それらは単に内部オブジェクトに追加されています。</li> <li>すべてのテストと数値変換は <code>calculate</code> メソッドで行われます。将来より複雑な式をサポートするために拡張されるかもしれません。</li> </ul> <div id="p6s1eptrnq" 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() { let methods = { "-": (a, b) => a - b, "+": (a, b) => a + b }; this.calculate = function(str) { let split = str.split(' '), a = +split[0], op = split[1], b = +split[2] if (!methods[op] || isNaN(a) || isNaN(b)) { return NaN; } return methods[op](a, b); } this.addMethod = function(name, func) { methods[name] = func; }; }</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/FMWINLjsTpghr6ia3Yoo?p=preview" target="_blank" data-plunk-id="FMWINLjsTpghr6ia3Yoo">サンドボックスでテストと一緒に解答を開く</a></p></div></div><button class="close-button task__answer-close" type="button" title="閉じる"></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="#ref-575" name="ref-575">名前へのマップ</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="タスクの重要度を表し、1 から 5 までです">重要性: 5</span></div><div class="task__content"><div class="task__formatted"><p><code>user</code> オブジェクトの配列を持っているとします。それは <code>user.name</code> を持っています。それは名前の配列に変換するコードを書いてください。</p> <p>例:</p> <div id="ugeeuvv1q5" 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: "John", age: 25 }; let pete = { name: "Pete", age: 30 }; let mary = { name: "Mary", 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">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="adr0y5s15m" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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: "John", age: 25 }; let pete = { name: "Pete", age: 30 }; let mary = { name: "Mary", age: 28 }; let users = [ john, pete, mary ]; let names = users.map(item => item.name); alert( names ); // John, Pete, Mary</code></pre> </div> </div> </div></div></div><button class="close-button task__answer-close" type="button" title="閉じる"></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="#ref-576" name="ref-576">オブジェクトへのマップ</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="タスクの重要度を表し、1 から 5 までです">重要性: 5</span></div><div class="task__content"><div class="task__formatted"><p>あなたは <code>user</code> オブジェクトの配列をもっており、それは <code>name</code>, <code>surname</code> と <code>id</code> を持っています。</p> <p>そこから、<code>id</code> と <code>fullName</code> (<code>fullName</code> は <code>name</code> と <code>surname</code> から生成されます)をもつオブジェクトの別の配列を作成するコードを書いてください。</p> <p>例:</p> <div id="76ny0wf93n" data-trusted="1" class="code-example" data-highlight="[{"start":6,"end":6}]"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let john = { name: "John", surname: "Smith", id: 1 }; let pete = { name: "Pete", surname: "Hunt", id: 2 }; let mary = { name: "Mary", surname: "Key", id: 3 }; let users = [ john, pete, mary ]; let usersMapped = /* ... your code ... */ /* usersMapped = [ { fullName: "John Smith", id: 1 }, { fullName: "Pete Hunt", id: 2 }, { fullName: "Mary Key", id: 3 } ] */ alert( usersMapped[0].id ) // 1 alert( usersMapped[0].fullName ) // John Smith</code></pre> </div> </div> </div><p>したがって、実際には、オブジェクトの1つの配列を別の配列にマップする必要があります。 ここで <code>=></code>を使ってみてください。</p> </div><button class="task__solution" type="button">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="v6a1yfdw94" data-trusted="1" class="code-example" data-highlight="[{"start":6,"end":9}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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: "John", surname: "Smith", id: 1 }; let pete = { name: "Pete", surname: "Hunt", id: 2 }; let mary = { name: "Mary", surname: "Key", id: 3 }; let users = [ john, pete, mary ]; let usersMapped = users.map(user => ({ fullName: `${user.name} ${user.surname}`, id: user.id })); /* usersMapped = [ { fullName: "John Smith", id: 1 }, { fullName: "Pete Hunt", id: 2 }, { fullName: "Mary Key", id: 3 } ] */ alert( usersMapped[0].id ); // 1 alert( usersMapped[0].fullName ); // John Smith</code></pre> </div> </div> </div><p>アロー関数の場合、追加の括弧が必要であることに注意してください。</p> <p>このように書くことはできません:</p> <div id="ddi01rudzn" data-trusted="1" class="code-example" data-highlight="[{"start":0,"cols":[{"start":36,"end":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 => { fullName: `${user.name} ${user.surname}`, id: user.id });</code></pre> </div> </div> </div><p>ご存知のように、2つのアロー関数があります: 本体なし <code>value => expr</code> と本体あり <code>value => {...}</code>。</p> <p>ここでは、JavaScript は <code>{</code> をオブジェクトの開始ではなく、関数本体の開始として扱います。ワークアラウンドは “通常の” 括弧でそれらを囲むことです。:</p> <div id="1w3afyoh9y" data-trusted="1" class="code-example" data-highlight="[{"start":0,"cols":[{"start":36,"end":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 => ({ fullName: `${user.name} ${user.surname}`, id: user.id }));</code></pre> </div> </div> </div><p>これで大丈夫です。</p> </div></div><button class="close-button task__answer-close" type="button" title="閉じる"></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="#ref-577" name="ref-577">ソートオブジェクト</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="タスクの重要度を表し、1 から 5 までです">重要性: 5</span></div><div class="task__content"><div class="task__formatted"><p>プロパティ <code>name</code> を持つオブジェクトの配列を取得し、それをソートする関数 <code>sortByName(users)</code> を書いてください。</p> <p>例:</p> <div id="pjecoxbb3x" 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: "John", age: 25 }; let pete = { name: "Pete", age: 30 }; let mary = { name: "Mary", age: 28 }; let arr = [ john, pete, mary ]; sortByName(arr); // now: [john, mary, pete] alert(arr[1].name); // Mary</code></pre> </div> </div> </div></div><button class="task__solution" type="button">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="zivl0w4auf" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 sortByName(arr) { arr.sort((a, b) => b.name > a.name ? 1 : -1); } let john = { name: "John", age: 25 }; let pete = { name: "Pete", age: 30 }; let mary = { name: "Mary", age: 28 }; let arr = [ john, pete, mary ]; sortByName(arr); // now sorted is: [john, mary, pete] alert(arr[1].name); // Mary</code></pre> </div> </div> </div></div></div><button class="close-button task__answer-close" type="button" title="閉じる"></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="#ref-578" name="ref-578">配列のシャッフル</a></h3><a class="task__open-link" href="/task/shuffle" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="タスクの重要度を表し、1 から 5 までです">重要性: 3</span></div><div class="task__content"><div class="task__formatted"><p>配列の要素をシャッフル(ランダムに再配置)する関数 <code>shuffle(array)</code> を書いてください。</p> <p><code>shuffle</code> の複数回実行すると、異なる要素順になります。例えば:</p> <div id="16yp1w371q" 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>すべての要素順は等しい発生確率である必要があります。例えば、<code>[1,2,3]</code> は <code>[1,2,3]</code> または <code>[1,3,2]</code> または <code>[3,1,2]</code> などに並び替えられる可能性があり、各ケースの発生確率は同じです。</p> </div><button class="task__solution" type="button">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><p>シンプルな解法は次のようになります:</p> <div id="6rwzoyjlhm" data-trusted="1" class="code-example" data-highlight="[{"start":0,"end":2}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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(() => Math.random() - 0.5); } let arr = [1, 2, 3]; shuffle(arr); alert(arr);</code></pre> </div> </div> </div><p>それはいくらか動作します。なぜなら <code>Math.random() - 0.5</code> は正または負のランダム値なので、ソート関数はランダムに要素を並び替えます。</p> <p>しかし、ソート関数はこのように使われることを意図していないので、すべての順列が同じ確率を持つわけではありません。</p> <p>例えば、下のコードを考えてみてください。<code>shuffle</code> を 1000000回実行し、可能性のあるすべての順序の出現数をカウントします。:</p> <div id="bli6k8a9cy" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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(() => Math.random() - 0.5); } // 可能性のあるすべての順列の出現数 let count = { '123': 0, '132': 0, '213': 0, '231': 0, '321': 0, '312': 0 }; for (let i = 0; i < 1000000; i++) { let array = [1, 2, 3]; shuffle(array); count[array.join('')]++; } // 結果を表示します for (let key in count) { alert(`${key}: ${count[key]}`); }</code></pre> </div> </div> </div><p>結果例は次の通りです(V8, 2017/7):</p> <div id="p5mfqkt72x" 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>明らかにバイアスがあることが分かります: <code>123</code> と <code>213</code> は他のものよりはるかに多く出現しています。</p> <p>このコードの結果は JavaScriptエンジンによって異なる可能性がありますが、このアプローチが信頼できないことが分かります。</p> <p>なぜ上手く動作しないのでしょうか?一般に、<code>sort</code> は “ブラックボックス” です: 配列と比較関数をそこに投げ、配列がソートされることを期待します。しかし、比較の完全なランダム性によりブラックボックスが狂ってしまい、どの程度狂ってしまうかはエンジンによって異なる具体的な実装に依存します。</p> <p>このタスクをするための他の良い方法があります。例えば、<a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates shuffle</a> と呼ばれる素晴らしいアルゴリズムがあります。この考えは、逆順に配列を見ていき、各要素をその前のランダムな要素と入れ替えます。</p> <div id="ja2kfcbyju" 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 > 0; i--) { let j = Math.floor(Math.random() * (i + 1)); // 0 から i のランダムなインデックス [array[i], array[j]] = [array[j], array[i]]; // 要素を入れ替えます } }</code></pre> </div> </div> </div><p>同じ方法でテストしてみましょう。:</p> <div id="exygt7ocgj" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 > 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 < 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>出力例です:</p> <div id="3eylj58qyl" 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>良い感じに見えます: すべての順列は同じ確率で表示されています。</p> <p>また、Fisher-Yates アルゴリズムはパフォーマンスの面で遥かに優れており、“ソート” のオーバヘッドがありません。</p> </div></div><button class="close-button task__answer-close" type="button" title="閉じる"></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="#ref-579" name="ref-579">平均年齢の取得</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="タスクの重要度を表し、1 から 5 までです">重要性: 4</span></div><div class="task__content"><div class="task__formatted"><p>プロパティ <code>age</code> をもつオブジェクtの配列を取得し、その平均を取得する関数 <code>getAverageAge(users)</code> を書いてください。</p> <p>平均の公式は <code>(age1 + age2 + ... + ageN) / N</code> です。</p> <p>例:</p> <div id="lrgwsv73m5" 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: "John", age: 25 }; let pete = { name: "Pete", age: 30 }; let mary = { name: "Mary", 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">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="ur1p9rm5ic" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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) => prev + user.age, 0) / users.length; } let john = { name: "John", age: 25 }; let pete = { name: "Pete", age: 30 }; let mary = { name: "Mary", 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="閉じる"></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="#ref-580" name="ref-580">ユニークな配列メンバをフィルタする</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="タスクの重要度を表し、1 から 5 までです">重要性: 4</span></div><div class="task__content"><div class="task__formatted"><p><code>arr</code> を配列とします。</p> <p><code>arr</code> のユニークなアイテムを持つ配列を返す関数 <code>unique(arr)</code> を作成してください。</p> <p>例:</p> <div id="7warv1j40c" 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 = ["Hare", "Krishna", "Hare", "Krishna", "Krishna", "Krishna", "Hare", "Hare", ":-O" ]; alert( unique(strings) ); // Hare, Krishna, :-O</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/oEK2tUvCEvPLas1hJNij?p=preview" target="_blank" data-plunk-id="oEK2tUvCEvPLas1hJNij">テストと一緒にサンドボックスを開く</a></p></div><button class="task__solution" type="button">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><p>配列要素を見ていきましょう:</p> <ul> <li>各アイテムに対して、返却する配列がすでにそれを持っているかをチェックします。</li> <li>もしそうであれば無視し、持っていなければ結果に追加します。</li> </ul> <div id="fzujg5ria5" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" 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 = ["Hare", "Krishna", "Hare", "Krishna", "Krishna", "Krishna", "Hare", "Hare", ":-O" ]; alert( unique(strings) ); // Hare, Krishna, :-O</code></pre> </div> </div> </div><p>このコードは機能しますが、そこには潜在的な性能問題があります。</p> <p>メソッド <code>result.includes(str)</code> は内部で配列 <code>result</code> を歩き、各要素を <code>str</code> と比較して一致するものを探します。</p> <p>従って、もし <code>result</code> の中に <code>100</code> 要素あり、誰も <code>str</code> にマッチしない場合、<code>result</code> 全体を歩き、正確に <code>100</code> 回の比較を行うことになります。また、 <code>10000</code> のように <code>result</code> が大きいと <code>10000</code> 回の比較になります。</p> <p>JavaScriptエンジンは非常に高速なので、それ自体は問題ではありません。なので、 <code>10000</code> 配列を見るのはマイクロ秒のレベルです。</p> <p>しかし、<code>for</code> ループの中で <code>arr</code> の各要素にこのようなテストをします。</p> <p>すると、<code>arr.length</code> が <code>10000</code> の場合、<code>10000*10000</code> = 1億回の比較になります。これは多いです。</p> <p>従って、この解答は小さい配列の場合にのみ良いです。</p> <p>さらにチャプター <span class="markdown-error">記事 "map-set-weakmap-weakset" が見つかりません</span> では、それを最適化する方法を見ていきます。</p> <div id="5hyig4utfe" 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) { let result = []; for (let str of arr) { if (!result.includes(str)) { result.push(str); } } return result; }</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/B9SqWrNqvebXK79toSIc?p=preview" target="_blank" data-plunk-id="B9SqWrNqvebXK79toSIc">サンドボックスでテストと一緒に解答を開く</a></p></div></div><button class="close-button task__answer-close" type="button" title="閉じる"></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="#ref-581" name="ref-581">配列からキー付けされたオブジェクトを作成する</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="タスクの重要度を表し、1 から 5 までです">重要性: 4</span></div><div class="task__content"><div class="task__formatted"><p><code>{id:..., name:..., age... }</code> といった形式でユーザの配列を受け取ったとしましょう。</p> <p>これから、<code>id</code> をキーとし、配列項目を値としたオブジェクトを作成する関数 <code>groupById(arr)</code> を作成してください。</p> <p>例:</p> <div id="c0fviigbjh" 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: "John Smith", age: 20}, {id: 'ann', name: "Ann Smith", age: 24}, {id: 'pete', name: "Pete Peterson", age: 31}, ]; let usersById = groupById(users); /* // 呼び出し後はこのようになります: usersById = { john: {id: 'john', name: "John Smith", age: 20} ann: {id: 'ann', name: "Ann Smith", age: 24}, pete: {id: 'pete', name: "Pete Peterson", age: 31}, } */</code></pre> </div> </div> </div><p>このような関数はサーバデータを扱う際に非常に便利です。</p> <p>このタスクでは <code>id</code> はユニークであるとします。同じ <code>id</code> を持つ配列項目はありません。</p> <p>この解法では配列の <code>.reduce</code> メソッドを使用してください。</p> <p><a href="https://plnkr.co/edit/NsyFPHJyHHYizNRm?p=preview" target="_blank" data-plunk-id="NsyFPHJyHHYizNRm">テストと一緒にサンドボックスを開く</a></p></div><button class="task__solution" type="button">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><div id="yb2znnpj7b" 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) => { obj[value.id] = value; return obj; }, {}) }</code></pre> </div> </div> </div><p><a href="https://plnkr.co/edit/ESWmHGusDBkLFxKb?p=preview" target="_blank" data-plunk-id="ESWmHGusDBkLFxKb">サンドボックスでテストと一緒に解答を開く</a></p></div></div><button class="close-button task__answer-close" type="button" title="閉じる"></button></div></div></div></div></div></div><div class="page__nav-wrap"><a class="page__nav page__nav_prev" href="/array" data-tooltip="配列"><span class="page__nav-text"><span class="page__nav-text-shortcut"></span></span><span class="page__nav-text-alternate">前のレッスン</span></a><a class="page__nav page__nav_next" href="/iterable" data-tooltip="反復可能なオブジェクト"><span class="page__nav-text"><span class="page__nav-text-shortcut"></span></span><span class="page__nav-text-alternate">次のレッスン</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">シェア</span><a class="share share_tw" href="https://twitter.com/share?url=https%3A%2F%2Fja.javascript.info%2Farray-methods" rel="nofollow"></a><a class="share share_fb" href="https://www.facebook.com/sharer/sharer.php?s=100&p%5Burl%5D=https%3A%2F%2Fja.javascript.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">チュートリアルマップ</span></a></div></div></div><div class="comments formatted" id="comments"><div class="comments__header"><h2 class="comments__header-title"><a href="#comments" name="comments">コメント</a></h2><div class="comments__read-before"><span class="comments__read-before-link">コメントをする前に読んでください…</span><div class="comments__read-before-popup"><div class="comments__read-before-popup-i"><ul><li>自由に記事への追加や質問を投稿をしたり、それらに回答してください。</li><li>数語のコードを挿入するには、<code><code></code> タグを使ってください。複数行の場合は <code><pre></code> を、10行を超える場合にはサンドボックスを使ってください(<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><li>記事の中で理解できないことがあれば、詳しく説明してください。</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:\/\/ja.javascript.info\/array-methods","identifier":"\/array-methods"}); };</script><script>var disqus_shortname = "ja-javascript-info";</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="チュートリアルマップ"></a><div class="sidebar__inner"><div class="sidebar__content"><div class="sidebar__section"><h4 class="sidebar__section-title">チャプター</h4><nav class="sidebar__navigation"><ul class="sidebar__navigation-links"><li class="sidebar__navigation-link"><a class="sidebar__link" href="/data-types">データ型</a></li></ul></nav></div><div class="sidebar__section"><h4 class="sidebar__section-title">レッスンナビゲーション</h4><nav class="sidebar__navigation"><ul class="sidebar__navigation-links"><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-551">アイテムの追加/削除</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-555">イテレート/反復: forEach</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-556">配列での検索</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-560">配列を変換する</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-566">Array.isArray</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-567">ほとんどのメソッドは “thisArg” をサポートします</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-568">サマリ</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">タスク (13)</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#comments">コメント</a></li></ul></nav></div><div class="sidebar__section"><div class="sidebar__section-title">シェア</div><a class="share share_tw sidebar__share" href="https://twitter.com/share?url=https%3A%2F%2Fja.javascript.info%2Farray-methods" rel="nofollow"></a><a class="share share_fb sidebar__share" href="https://www.facebook.com/sharer/sharer.php?s=100&p[url]=https%3A%2F%2Fja.javascript.info%2Farray-methods" rel="nofollow"></a></div><div class="sidebar__section"><a class="sidebar__link" href="https://github.com/javascript-tutorial/ja.javascript.info/blob/master/1-js/05-data-types/05-array-methods" rel="nofollow">GitHubで編集</a></div></div></div></div></div></div><div class="page-footer"><ul class="page-footer__list"><li class="page-footer__item page-footer__item_copy">© 2007—2025 Ilya Kantor</li><li class="page-footer__item page-footer__item_about"><a class="page-footer__link" href="/about">プロジェクトについて</a></li><li class="page-footer__item page-footer__item_contact"><a class="page-footer__link" href="/about#contact-us">コンタクト</a></li></ul></div></body></html>