C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

二次元配列を格納したListの比較

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■90514 / inTopicNo.1)  二次元配列を格納したListの比較
  
□投稿者/ B.B (16回)-(2019/03/16(Sat) 18:29:27)

分類:[C#] 

Visual Studio 2017

お世話になっております

下記のようなリストがあります
var hogeList = new List<Point[,]>() {
    new Point[,] { { new Point(10, 10) }, { new Point(20, 20) } },
    new Point[,] { { new Point(100, 100) }, { new Point(120, 120) } },
};

このリストに次の配列が存在しているか調べたいのです
var hoge = new Point[,] { { new Point(10, 10) }, { new Point(20, 20) } };

Containsでは思うような結果が出ませんでした
bool result = hogeList.Contains(hoge); //falseになる


どのようにすれば調べられるでしょうか、よろしくお願いします

引用返信 編集キー/
■90515 / inTopicNo.2)  Re[1]: 二次元配列を格納したListの比較
□投稿者/ キングダム (13回)-(2019/03/16(Sat) 21:01:27)
No90514 (B.B さん) に返信

> どのようにすれば調べられるでしょうか、よろしくお願いします

List.Containsは要素のEqualsを呼び出してると思います
配列以外のクラスを作ってEqualsをオーバーライドすれば確かめられます

配列のEqualsは要素のEqualsを呼び出さないんじゃないかと思います
PointのEqualsをオーバーライドすれば確かめられます

配列をリストに変えたり
Containsを独自に実装したりとかでなんとかなりそうですね
引用返信 編集キー/
■90517 / inTopicNo.3)  Re[1]: 二次元配列を格納したListの比較
□投稿者/ mayo (1回)-(2019/03/17(Sun) 12:24:24)
2019/03/17(Sun) 12:32:29 編集(投稿者)
2019/03/17(Sun) 12:31:48 編集(投稿者)
2019/03/17(Sun) 12:26:18 編集(投稿者)
2019/03/17(Sun) 12:25:59 編集(投稿者)

No90514 (B.B さん) に返信


VBで書いたものをC#に変換しているので、変な構文になってるかもしれませんが....

//検索対象を1次元配列にしておく
var hoge ={new Point(10, 10),new Point(20, 20)};
var result = hogeList.Select(x => x.Cast<Point>()).Any(x => x.SequenceEqual(hoge));

引用返信 編集キー/
■90518 / inTopicNo.4)  Re[2]: 二次元配列を格納したListの比較
□投稿者/ B.B (18回)-(2019/03/17(Sun) 16:07:10)
No90515 (キングダム さん) に返信

> 配列をリストに変えたり
> Containsを独自に実装したりとかでなんとかなりそうですね

配列をリストに変えようと思います。リストならSequenceEqualが使えました。
ご助言ありがとうございました
引用返信 編集キー/
■90519 / inTopicNo.5)  Re[2]: 二次元配列を格納したListの比較
□投稿者/ B.B (19回)-(2019/03/17(Sun) 16:09:30)
No90517 (mayo さん) に返信

> var result = hogeList.Select(x => x.Cast<Point>()).Any(x => x.SequenceEqual(hoge));

LINQの書き方を参考にさせてもらいます。
ご助言ありがとうございました
引用返信 編集キー/
■90520 / inTopicNo.6)  Re[3]: 二次元配列を格納したListの比較
□投稿者/ B.B (20回)-(2019/03/17(Sun) 16:36:19)
ご助言により以下のようにして解決しました

・配列をリストにする
・LINQを使いSequenceEqualで比較する


using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var hoge = new List<Point> { new Point(10, 10), new Point(20, 20) } ;

            var hogeList = new List<List<Point>>() {
                new List<Point> { new Point(10, 10), new Point(20, 20) },
                new List<Point> { new Point(100, 100), new Point(120, 120) }
            };

            var result = hogeList.Any(s => s.SequenceEqual(hoge));

            MessageBox.Show(result.ToString()); //True
        }
    }
}

解決済み
引用返信 編集キー/
■90526 / inTopicNo.7)  Re[4]: 二次元配列を格納したListの比較
□投稿者/ PANG2 (269回)-(2019/03/18(Mon) 12:31:54)
No90520 (B.B さん) に返信
> ・配列をリストにする

次元が落ちていますね。

元の配列
var hogeList = new List<Point[,]>();

をリスト化するのであれば、

var hogeList = new List<List<Point[]>>();



var hogeList = new List<List<List<Point>>>();

でしょう。

引用返信 編集キー/
■90535 / inTopicNo.8)  Re[5]: 二次元配列を格納したListの比較
□投稿者/ PANG2 (270回)-(2019/03/19(Tue) 10:27:35)
2次元配列をジャンク配列に変えて、

var hogeList = new List<Point[][]>();
bool result = hogeList.Any(s => ((IStructuralEquatable)s).Equals(hoge, StructuralComparisons.StructuralEqualityComparer));

---
var hogeList = new List<Point[,]>();
var hogeList = new List<List<Point[]>>();
var hogeList = new List<List<List<Point>>>();
は難しいです。
分かる方いますか?
引用返信 編集キー/
■90537 / inTopicNo.9)  Re[6]: 二次元配列を格納したListの比較
□投稿者/ Hongliang (770回)-(2019/03/19(Tue) 11:29:28)
> 2次元配列をジャンク配列に変えて、
ジャグ配列です。ジグザグ。

> var hogeList = new List<Point[,]>();
各次元の長さの比較を加えれば、SequenceEqualでも事足りますね。
int len0 = hoge.GetLegnth(0), len1 = hoge.GetLength(1);
hogeList.Any(_p => _p.GetLength(0) == len0 && _p.GetLength(1) == len1
  && _p.Cast<Point>().SequenceEqual(hoge.Cast<Point>());

> var hogeList = new List<List<Point[]>>();
> var hogeList = new List<List<List<Point>>>();
もうLINQこねくり回すよりも素直にループした方が良い気がするけれどもこんなのとか。
hogeList.Any(_p => _p.Count == hoge.Count
    && _p.Zip(hoge, (_a, _b) => new { a = _a, b = _b })
         .All(_zip => _zip.a.SequenceEqual(_zip.b)));

引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ