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

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

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

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

Q&A

解決済

3回答

14196閲覧

C#でListに対して部分一致したインデックスのデータをリムーブするには

MiyamotoSatoshi

総合スコア30

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

0グッド

0クリップ

投稿2016/09/07 05:30

■仕様の背景
URLリスト(コードのurlList)を使ってダウンロードを行う、
すでにダウンロード済みのファイル名は
1行づつファイルに書き込まれて保存されている(コードのdownLoadedListと同一)

■メソッドでやりたい事

すでにダウンロード済みのファイルはダウンロードする必要がないため
URLリストから削除する。
つまりURL内に必ずファイル名が含まれているため部分一致検索し、
そのインデックスの要素をURLリストから削除する。

■質問とコード
下記コードでリストに対して部分一致した場合、
インデックスを取得してそのインデックスのデータを削除するというコードを書いたのですが
冗長なのではないかと考えており質問しました。

C#

1// 中身は https:// + ファイル名 + シグネチャ 2List<string> urlList = URLのリスト; 3int loopcnt = urlList.Count; 4 5// 中身は ダウンロード済みのファイル名 6List<string> downLoadedList = ファイル名リスト 7int downLoadCount = downLoadedList.Count; 8 9for (int i = 0; i < loopcnt; i++) 10{ 11 for(int j = 0; j < downLoadCount;j++) 12 { 13 // 部分一致したか? 14 if(urlList.Contains(downLoadedList[j]) == true) 15 { 16 // 部分一致したインデックスを取得 17 var foundIndex = urlList.Select((item, index) => new { Index = index, Value = item }) 18 .Where(item => item.Value.IndexOf(downLoadedList[j]) >= 0) 19 .Select(item => item.Index); 20 // 指定インデックスのURLを削除 21 urlList.RemoveAt(foundIndex.ToArray()[0]); 22 } 23 } 24}

■開発環境
Unity5.4.0f3(C#4.0)
Windows7
.NetFrameWork3.5

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

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

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

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

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

omochi

2016/09/07 06:00

downLoadedListはファイル名のみでURLではないですよね?
MiyamotoSatoshi

2016/09/07 06:24

そうです、URLにすると文字列として長すぎるためファイル名にしました。
guest

回答3

0

Containsで評価されるのはstringのEqualsなので部分一致できないと思われます

追記

C#

1// 部分一致部分 2 if(urlList[i].indexOf(downLoadedList[j]) > -1) 3 { 4 urlList.Remove(urlList[i]); 5 } 6

投稿2016/09/07 06:42

編集2016/09/07 07:00
omochi

総合スコア410

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

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

r_ym

2016/09/07 08:08 編集

#コメント削除 失礼しました、私の勘違いでした。 ※string.ContainsとList<T>.Containsを間違えていました。
guest

0

ベストアンサー

二重ループのところはこんな感じでいかがですか?

urlList.RemoveAll(url => downLoadedList.Exists(dl => url.Contains(dl)));

投稿2016/09/07 05:47

r_ym

総合スコア79

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

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

MiyamotoSatoshi

2016/09/07 07:52

できましたが、ContainsのBool値に対してExistsがどのような作用を及ぼしているのかわからないので、考え中です。
r_ym

2016/09/07 08:02

Existsは「存在するか?」でいいと思います。 downLoadedList.Exists(dl => url.Contains(dl))) は「 downLoadedList の中に url の一部に一致するものが存在するか?」 urlList.RemoveAll()で、「downLoadedList の中に url の一部に一致するものが存在するなら削除する」 という感じになります。
MiyamotoSatoshi

2016/09/07 08:30

ありがとうございます、 Existsの宣言をみたところ Exists(Predicate<T> match) となっており 「downLoadedList の中に url の一部に一致するものが存在する」というものを 削除という事が理解できました。
guest

0

Except() が使えます。一行になります。

csharp

1var removedList = urlList.Except(downloadedList);

追記

urlListの要素の文字列に対して部分一致で除外するならこうですかね。

csharp

1var removedList = urlList.Where(url => downloadedList.All(name => !url.Contains(name)));

投稿2016/09/07 05:46

編集2016/09/07 07:09
tamoto

総合スコア4103

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

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

MiyamotoSatoshi

2016/09/07 06:45 編集

まだ実際のコードでは試してはいないのですが、質問です。 Exceptは部分一致に対応していないみたいです。 downloadedListにはurlListの文字列の一部しか入ってない状態です。 下記のようなコードでテストしてみました。 public void OnClicked() { List<string> urlList = new List<string>() { "あいうえお", "かきくけこ", "さしすせそ" }; List<string> downloadedList = new List<string>() { "お", "こ", "そ" }; var removedList = urlList.Except(downloadedList); List<string> endList = removedList.ToList(); }
tamoto

2016/09/07 07:00

質問に記載されているコードでは if(urlList.Contains(downLoadedList[j]) == true) となっており、stringの同値比較を行っているので、 この回答でも同等のものを実装しています。
tamoto

2016/09/07 07:10

部分一致で除外するコードを回答に追記しました。
MiyamotoSatoshi

2016/09/07 08:21

ありがとうございます。 そもそも質問にあったのがバグコードでした。 下記を参考に作ったのですが、部分一致検索時のWhere句が抜けていました。 http://www.atmarkit.co.jp/ait/articles/1412/02/news129.html 下記テストコードを書いたところ、 Match0側のみログが出力され部分一致検索を正しく判定できていることを 確認できました。 public void CheckPartialMatch() { List<string> urlList = new List<string>() { "あいうえお", "かきくけこ", "さしすせそ" }; List<string> downloadedList = new List<string>() { "そ", "た" }; var Match0 = urlList.Where(item => item.Contains(downloadedList[0]) == true).ToList(); foreach(string factor in Match0) { Debug.Log("match0=" + factor); } var Match1 = urlList.Where(item => item.Contains(downloadedList[1]) == true).ToList(); foreach (string factor in Match1) { Debug.Log("match1=" + factor); } }
MiyamotoSatoshi

2016/09/07 08:25

>部分一致で除外するコードを回答に追記しました。 追記ソースが動作することも確認しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問