質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

249閲覧

2次元配列同士のデータ抽出について

rena_168

総合スコア72

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

2クリップ

投稿2023/05/30 11:56

実現したいこと

以下の2つの2次元配列があります。
ary01の1列目と2列をキーに、
ary02の1列目と2列目が同じ値で、かつヒットした行データの3列目の値が0より
大きい3列目の数値をary01の5列目に追加したいです。

最初、ary01の300個の数分、ary02の2000個分の中でループして見つかったものをary01に
代入しましたが、3分待たないと結果が返ってこなかったので、パフォーマンス向上を考え、
2つの配列の差分を取得するほうが処理的に早いかなと思っていますが、いかがでしょうか。

前提

ary01のキー内容(1列目、2列目)は必ずしもary02に存在するとは限らないです。

コード

javascript

1 const ary01 = [ 2 ["BF000351", "A001-001", "1", "AAA"], 3 ["A", "Alice", "3", "BBB"], 4 ["A", "Chris", "4", "CCC"], 5 ["B", "Chris", "5", "DDD"], 6 ["B", "Chris", "6", "EEE"], 7 ["C", "Davis", "7", "FFF"] 8 ]; 9 const ary02 = [ 10 ["AA", "Bill", "1", "AAA"], 11 ["BF000351", "A001-001", 1200, "AAA"], 12 ["B", "Chris", "6", "EEE"], 13 ["B", "Chris", 6, "EEE"], 14 ["B", "Chris", 0, "EEE"], 15 ["AB", "Alice", "3", "BBB"], 16 ["AC", "Chris", "4", "CCC"], 17 ["C", "Davis", "7", "FFF"] 18 ]; 19 20 // const output = ary01.filter((value) => ary02.some(ary => ary.every((a, i) => a === value[i]))); 21 const unique_A = ary01.filter(function(e, index){ 22 return !ary01.some(function(e2, index2){ 23 console.log("e[0] = " + e[0] + "; e2[0] = " + e2[0]); 24 return index > index2 && e[0] == e2[0] && e[1] == e2[1]; 25 }); 26 }); 27 console.log(unique_A);

実行結果

[ [ 'BF000351', 'A001-001', '1', 'AAA' ],
[ 'A', 'Alice', '3', 'BBB' ], ←このデータがあってはいけないですが。。。
[ 'A', 'Chris', '4', 'CCC' ], ←このデータがあってはいけないですが。。。
[ 'B', 'Chris', '5', 'DDD' ],
[ 'C', 'Davis', '7', 'FFF' ] ]

疑問点

ary01のAとary02のABは一致してないから実行結果にあってはいけないはずなのに、
なんでヒットして出てきたのでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YellowGreen

2023/05/30 23:05 編集

ary01と何を比較していますか? コメント行以外には、ary02がありません。 ["B", "Chris", "6", "EEE"], は、 ["B", "Chris", "5", "DDD"], があるので抽出されなかったのでしょうね。
YellowGreen

2023/05/31 01:26 編集

一致するものを抽出するのも不一致を抽出するのも、今のような方法だと一致するものがあったら処理を抜けて一致を取得(不一致を取得できない)または最後まで確認して(一致を取得できないで)不一致を取得するのですから処理回数は同じ程度になるのではないでしょうか。 for(of)ループかforEachかfilterかでどのくらい違いがあるのでしょうか。forEachはbreakで抜けられないので一番遅いような気がします。
guest

回答2

0

自己解決

ご助言をいただき、自己解決できました。

以下コードでできました。

javascript

var output = ary01.filter(function(e,index){
return !ary02.some(function(e2,index2){
if (e[0] == e2[0] && e[1] == e2[1]) {
e[2] = e2[2];
}
})
})

投稿2023/05/31 03:35

rena_168

総合スコア72

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YellowGreen

2023/05/31 08:29 編集

当方でも興味があったので、 約300件と約20000件(2万です)のデータで追試をしてみましたが、 const ary03 = []; for(const e of ary01) { for(const e2 of ary02) { if (e[0] == e2[0] && e[1] == e2[1] && e[2] == e[2]) { ary03.push(e); break; } } } のコードと const ary03 = ary01.filter(e => ary02.some(e2 => e[0] == e2[0] && e[1] == e2[1] && e[2] == e2[2]) ); のコードを開始前と開始後との時刻を取得してミリ秒単位で比較してもデータのシートへの記入時間を含めて どちらも100ミリ秒前後の実行時間でした。
guest

0

「差分を取得する」というのがどういう処理なのかわかりませんが、自分なら ary02 を以下のような辞書形式に変換してからマッチングを行います。

js

1{ 2 "AA Bill": 1, 3 "BF000351 A001-001": 1200, 4 "B Chris": 6, 5 "AB Alice": 3, 6 "AC Chris": 4, 7 "C Davis": 7 8}

投稿2023/05/30 21:38

int32_t

総合スコア20832

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問