複数のListを比較する方法
解決済
回答 5
投稿
- 評価
- クリップ 0
- VIEW 8,533
これらリストすべての要素をチェックして、共通の要素を抜き出したいのですが
一番簡潔に行うにはどのように処理を組み立てればよいでしょうか?
ちなみに要素が1つもないNULLのListも含まれています。
私が考えた方法は以下の通りです。
List<String> commonList = new ArrayList<String>(); //共通要素が入る
// list01に要素が含まれる場合
if( list01 != null ){
for(int i=0; i<list01.size(); i++){
if( list02.contains(list01.get(i))
&& list03.contains(list01.get(i))
&& list04.contains(list01.get(i))
&& list05.contains(list01.get(i))
&& list06.contains(list01.get(i))
&& list07.contains(list01.get(i))
&& list08.contains(list01.get(i))
&& list09.contains(list01.get(i))
&& list10.contains(list01.get(i))
){
commonList.add(i);
}
}
}
// list01はnullだがlist02に要素が含まれる場合
if( commonList.size() == 0 && list02 != null ){
for(int i=0; i<list02.size(); i++){
if( list01.contains(list02.get(i))
&& list03.contains(list02.get(i))
&& list04.contains(list02.get(i))
&& list05.contains(list02.get(i))
&& list06.contains(list02.get(i))
&& list07.contains(list02.get(i))
&& list08.contains(list02.get(i))
&& list09.contains(list02.get(i))
&& list10.contains(list02.get(i))
){
commonList.add(i);
}
}
}
// list01、list02はnullだがlist03に要素が含まれる場合
if( commonList.size() == 0 && list03 != null ){
省略
}
以下同様
・
・
・
このやり方だと比較するListが増えるたびにコードも増えて修正もしづらくなってしまいます。
もっと簡単に行える方法はないでしょうか?
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+3
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
checkベストアンサー
0
1. 2 つの list の共通部分を list で返すメソッドを定義します。
List<String> get_common(List<String> l1, List<String>l2) {
...
}
l1 や l2 が null の場合も考慮して実装します。
さらに l1, l2 の要素数が少ない方で ループを回すなどの工夫をしても良いかもしれません。
2. List2, ... List10 を Lists[0] .. Lists[8] に代入しておきます。
(面倒なら、 list1, ... list10 を lists[0], .. lists[0] に代入しても構いません。)
3. List<String> ans = list1;
for (List<String> list:Lists) {
ans = get_common(ans, list);
if (ans.isEmpty()) {
break;
}
}
として、ループを抜けた時点で ans には list1, ... list10 の共通要素が設定されています。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
list01
がnull
の場合、list02
の中でlist01.contains
を呼び出すとNullPointerException
になってしまいますね。
そこをどうすれば良いのか分かりませんでしたので、まずは「リストが
null
の場合は含まれるのと同じにカウントする」という前提で考えてみました。
リストのリストを作れば、リストの数が増えても同じように処理できます。
以下のサンプルコードでは、お望みのものとは動作が異なるかもしれませんが、ここではリストが増えてもコードがほとんど増えないようにする点だけを参考にしてください。
// Java5以降
// import java.util.*;
List<String> list01 = ... ;
List<String> list02 = ... ;
List<String> list03 = ... ;
List<List<String>> a = new ArrayList<List<String>>();
Collections.addAll(a, list01, list02, list03);
List<String> commonList = new ArrayList<String>();
for (List<String> list : a) {
if (list != null) {
for (String s : list) {
int count = 1;
for (List<String> listB : a) {
if (listB == list)
continue;
if (listB == null || listB.contains(s))
++count;
}
if (count == a.size()) // nullでないすべてのlistに含まれていた
commonList.add(s);
}
}
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
var list01 = [1,2,3,4,5];
var list02 = [1,2,3,4,5];
var list03 = [1,2,3,4,5];
var list = [list01,list02,list03];
var buf = {}; // hash map, 重複比較用
var result =[]; // 重複要素格納用
for(val in list){
for(val2 in list[val]){
// bufに探索キーが存在しなければ、bufにキーを追加
if(buf[val2] === undefined){
// key追加。値はなんでも良い。
buf[val2] = 1;
} else {
// 重複したキーが存在する場合、結果Arrayに格納
result.push(val2);
}
}
}
// 終了時にはresultに重複する要素が全て格納されている
console.log(JSON.stringify(result));
まず、List01~List10は、argiusさんの様に一つのリストに格納します。
次に、このリストを2重のforで、最終要素まで一気に探索します。
その際、連想配列(たぶんJavaではHashMap?)に最終要素をキーとして値を入れます。
キーが存在しなければ、連想配列に追加し、キーが存在する場合は結果用ArrayListに追加します。
この様にすると、一見無駄に複雑化している様に見えるかもしれませんが、
全要素数 * 1の比較回数で、全ての重複要素を抜き出す事が可能です。
また、HashMapのキー探索は非常に高速なので、このやり方であれば数千万要素程度までなら一瞬で探索できるはずです。
Javaで説明できなくて申し訳ないですが、ご参考になれば幸いです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
List<String> allList = new ArrayList<String>()
allList.addAll(list01);
allList.addAll(list02);
(省略)
Comparator<String> comp = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
};
Collections.sort(allList , comp); // ソート処理
ソートしたものをループで見て、
同じ要素が元々のリストの数(例だと10個)続いていれば、
ずべてのリストに存在する共通要素となります。
内部でまわすループ数は他と大して変わりませんが、
Comparatorを作ればソースはかなり簡潔になると思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.23%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2014/12/08 19:53
コレクションはarrayListとMapしか使ったことがないのでsetについて調べてみます。便利なメソッドがあるんですね。
2016/11/24 11:08