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

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

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

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

LINQ

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

Q&A

解決済

1回答

1701閲覧

インデックス付きEnumerable.Selectメソッドで匿名メソッド(ラムダ式)がタプルを返すときにエラーとなる理由をしりたい。

teracot

総合スコア1

C#

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

LINQ

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

0グッド

0クリップ

投稿2021/05/10 22:13

編集2021/05/11 02:09

前提・実現したいこと

Atcoderの問題でわからないところを理解したい。

問題リンクB - Palace


以下のコードを書いたときに、エラーとなる理由を知りたい。
②、③のコードではなぜいけるのか知りたい。


④のコードのときエラーとなる理由を知りたい。
Enumerable.Minメソッドは、Minメソッドをかける配列の内容の型がIComparableを実装しなければならない。
というのはわかる。
a,匿名型にはIComparableを実装できない?
b,タプル型のIComparableのCompareToメソッドの実装はどこで見れますか?(どういうルールで比較するの知りたい)

(↓↓↓追加情報↓↓↓)
問題文は以下のリンクにあります
問題リンクB - Palace

コンソールへの入力例1
2
12 5
1000 2000

コンソールへの入力例2
3
21 -11
81234 94124 52141

ご回答、ご教授宜しくお願いいたします。。。。!!!

発生している問題・エラーメッセージ

①エラーメッセージ CS1061:'(double,int)'に'index'の定義が含まれておらず、型'(double,int)'の最初の引数を受け付けるアクセス可能な拡張メソッド'index'が見つかりませんでした。 ④エラーメッセージ ハンドルされていない例外: System.ArgumentException: 少なくとも 1 つのオブジェクトで IComparable を実装しなければなりません。

該当のソースコード

C#

1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading.Tasks; 6 7namespace AtCoder 8{ 9 class B_Palace 10 { 11 static void Main( string[] args ) 12 { 13 int n = int.Parse(Console.ReadLine()); 14 15 int[] inputs = Console.ReadLine().Split(' ').Select(int.Parse).ToArray(); 16 int t = inputs[0]; 17 float a = (float) inputs[1]; 18 19 int[] elevations = Console.ReadLine().Split(' ').Select(int.Parse).ToArray(); 20 21 //ダメ① index+1 22 //var res = elevations.Select(x => t - x * 0.006).Select(( double num, int index ) => (Math.Abs(num - a), index+1)).Min(x => x).index; 23 24 //OK② indexそのまま 25 var res = elevations.Select(x => t - x * 0.006).Select(( double num, int index ) => (Math.Abs(num - a), index)).Min(x => x).index; 26 27 //OK③ Item2を使う。 28 //var res = elevations.Select(x => t - x * 0.006).Select(( double num, int index ) => (Math.Abs(num - a), index = index + 1)).Min(x => x).Item2; 29 //var res = elevations.Select(x => t - x * 0.006).ToArray().Select(( s, index ) => new Tuple<double, int>(Math.Abs(s - a), index + 1)).Min(d => d).Item2; 30 31 //ダメ④ 匿名型 32 //var res = elevations.Select(x => t - x * 0.006).Select(( double num, int index ) =>new { Diff = Math.Abs(num - a), Index = index }).Min(x => x).Index; 33 34 Console.WriteLine(res + 1); 35 } 36 } 37} 38

試したこと

・タプルについて理解する。
・index付きSelectメソッドについて理解する。
・匿名型について理解する。

補足情報(FW/ツールのバージョンなど)

Microsoft Visual Studio Community 2019
Version 16.9.4

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/05/11 00:44

コンソールからの入力が意味不明です。最終的に elevations を使うようですが、あなたが何を入力したかによって結果が変わってくるのでは?
teracot

2021/05/11 01:12

閲覧ありがとうございます。 コンソールの入力例など書き込みました。
guest

回答1

0

ベストアンサー

1の2回めのSelectはIEnumerable<(double, int)>と要素名なしのタプルですが、
2の方はIEnumerable<(double, int index)>とタプルの要素名が推論されています。

なので2の方はindexでアクセスできています。

1の方でも要素名を明記すればエラーになりません:

C#

1var res = elevations.Select(x => t - x * 0.006).Select(( double num, int index ) => (Math.Abs(num - a), index : index+1)).Min(x => x).index;

a,匿名型にはIComparableを実装できない?

Javaみたいに匿名型にインターフェースを実装することはできません。

b,タプル型のIComparableのCompareToメソッドの実装はどこで見れますか?(どういうルールで比較するの知りたい)

実装

投稿2021/05/11 02:29

ozwk

総合スコア13512

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

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

teracot

2021/05/11 04:12

回答ありがとうございます。。 確かに①のSelectメソッドの上にマウスカーソルを当てると、IEnumerable<(double, int)>が返されていると表示されて、 ②のSelectメソッドの上にマウスカーソルを当てると、Enumerable<(double,int index)>が返されていました! タプルフィールドの名前は、タプル プロジェクション初期化子?というのによって、 匿名メソッドでの引数の変数名を、"そのまま"タプルのインスタンスを作るのに使うと、 タプルフィールド名が推論(適用?)されることがわかりました。 またTuple型の実装のリンクも教えていただきありがとうございました。 あまり理解できませんでしたが、Tuple<T1,T2>のCompereToメソッドの実装を見ると、 まず1つ目のタプルフィールドから比較されて、1つ目のタプルフィールドが同値のとき、 2つ目のタプルフィールドが比較されてることがわかりました。。 質問してよかったです。。より理解が深まりました!! 本当にありがとうございました。。!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問