【JavaScript】すべてのサブ配列に共通する文字列だけを抽出する方法
次のような、配列の中にさらに配列が入っているデータ(ネストされた配列)を考えてみましょう。
const arr = [ ['foo', 'bar', 'hey', 'oi'], ['foo', 'bar', 'hey'], ['foo', 'bar', 'anything'], ['bar', 'anything'] ]
このような配列を受け取り、すべてのサブ配列に共通して含まれている文字列だけを集めた新しい配列を返す関数を作成します。
実装の考え方
ここで活躍するのが Array.prototype.reduce() です。reduce の初期値として最初のサブ配列を使い、各ステップで「現在の蓄積結果の各要素が、次のサブ配列にも存在するか」を filter() で判定していきます。こうすることで、処理が進むにつれて共通する要素だけが残り続けます。
コード例
const arr = [
['foo', 'bar', 'hey', 'oi'],
['foo', 'bar', 'hey'],
['foo', 'bar', 'anything'],
['bar', 'anything']
];
const commonArray = arr => {
return arr.reduce((acc, val, index) => {
return acc.filter(el => val.indexOf(el) !== -1);
});
};
console.log(commonArray(arr));
実行結果
コンソールには次のように出力されます。
['bar']
4つのサブ配列すべてに存在しているのは 'bar' だけなので、結果は ['bar'] になります。'foo' や 'hey' などは一部のサブ配列にしか存在しないため、途中の段階で除外されている点に注目してください。
補足:includes() を使ったより読みやすい書き方
indexOf() の代わりに、ES2015 以降で利用できる includes() を使うと、コードの意図がより明確になり、可読性が向上します。
const commonArray = arr => {
return arr.reduce((acc, val) => acc.filter(el => val.includes(el)));
};
どちらの書き方でも動作結果は同じですが、includes() の方が「含まれているかどうか」を直接表現できるため、モダンな JavaScript コードではこちらが推奨されます。
-
JavaScriptで配列内のすべてのゼロを末尾に移動する方法
問題概要 JavaScriptで、数値などのリテラルを含む配列を受け取る関数を作成することを考えます。この配列には、いくつかの0(ゼロ)が含まれている可能性があります。求められているのは、すべてのゼロを配列の末尾へ移動させると同時に、ゼロ以外の要素の相対的な順序は元のまま維持するという処理です。 解決策のコード例 以下がその実装コードです。 { const res = []; let currIndex = 0; for(let i = 0; i < arr.length; i++){ const el = arr[i]; if(el === 0){
-
JavaScriptで単位が混在する重量値の配列を並べ替える方法
問題グラム(G)、キログラム(KG)、トン(T)という3つの単位が混在した重量値を含む文字列の配列を受け取り、軽い順から重い順に並べ替えるJavaScript関数を作成する必要があります。課題となるのは、単位が異なるため文字列同士を直接比較できないという点です。そこで、まず各値を共通の単位(ここではキログラム)に変換してから比較を行うアプローチが有効です。解決策以下の手順で実装します。各文字列の末尾から単位(G / KG / T)を判定する数値部分を抽出し、単位に応じてキログラム基準の値へ変換する(T は 1000 倍、G は 0.001 倍)Array.prototype.sort() のコ