DOBON.NETプログラミング道掲示板

ツリー一括表示

Nomalアイコン 文字列構造体のListのソート /あおぞら (18/11/13(Tue) 14:30) #34025
Nomalアイコン Re[1]: 文字列構造体のListのソート /魔界の仮面弁士 (18/11/13(Tue) 14:50) #34026
  └Nomalアイコン Re[2]: 文字列構造体のListのソート /あおぞら (18/11/13(Tue) 15:21) #34027
    └Nomalアイコン Re[3]: 文字列構造体のListのソート /魔界の仮面弁士 (18/11/13(Tue) 15:35) #34028
      ├Nomalアイコン Re[4]: 文字列構造体のListのソート /魔界の仮面弁士 (18/11/13(Tue) 15:43) #34029
      └Nomalアイコン Re[4]: 文字列構造体のListのソート /あおぞら (18/11/14(Wed) 10:28) #34030 解決み!
        └Nomalアイコン Re[5]: 文字列構造体のListのソート /魔界の仮面弁士 (18/11/14(Wed) 11:06) #34033 解決み!


親記事 / ▼[ 34026 ]
■34025 / 親階層)  文字列構造体のListのソート
□投稿者/ あおぞら 一般人(1回)-(2018/11/13(Tue) 14:30:58)
  • アイコン環境/言語:[Win10 64Bit  C#FormApp Framework4.6.1] 
    分類:[.NET] 

    文字列構造体のListのソートがしたいのですが、うまくいきません。
    
            public struct Items
            {
                public string itemName;
                public string value;
                public string unit;
                public string oder;
            };
            public List<Items> itemaList = new List<Items>();
    
    このitemListには20レコードのデータが必要な順番で入っているのですが、oderには
    1〜9と無視するデータを表す0が格納されており、この1〜9のならびでデータを取り出したい
    時もあります。そこで、
    
        var tes = from num in itemList
                      where int.Parse(num.oder) > 0 && int.Parse(num.oder) <= 9
                      select int.Parse(num.oder);
    
    としてみたのですが、上手く値を取得できませんでした。
    どうしたらoder順にデータを取り得だせるでしょうか。
    御教示ください。

違反を報告
[ □ Tree ] 返信 削除キー/

▲[ 34025 ] / ▼[ 34027 ]
■34026 / 1階層)  Re[1]: 文字列構造体のListのソート
□投稿者/ 魔界の仮面弁士 大御所(1162回)-(2018/11/13(Tue) 14:50:46)
  • アイコンNo34025に返信(あおぞらさんの記事)
    > 文字列構造体のListのソートがしたいのですが、うまくいきません。
    文字列ソートですので、並び順は
     "2", "12", "123", "234"
    ではなく、
     "12", "123", "2", "234"
    になりますが、そこは大丈夫でしょうか。


    > oderには1〜9と無視するデータを表す0が格納されており、
    oder は int や char ではなく string なのですよね。

    ということは 0,1〜9 ではなく、"0","1"〜"9" の間違いであろうかと思いますが、
    それ以外の値たとえば "" や null や "0xA" などは入らないという前提でよろしいでしょうか。

    20 レコードのうち、orer 値が同じ値だった場合の並び順は何に従うのでしょうか。
    List<> の格納順を維持するべきなのか、それともフィールドの内容で判断するのか、
    質問内容からははっきりしません。

    また、order が "0" だった場合、「そのデータは存在しないものとして、ソート結果から取り除く」のでしょうか。
    それとも "0" なデータは「どうせ無視されるので、ソート結果の何番目にあっても気にしない」のでしょうか。



    > どうしたらoder順にデータを取り得だせるでしょうか。
    orderby で。
違反を報告
[ 親 34025 / □ Tree ] 返信 削除キー/

▲[ 34026 ] / ▼[ 34028 ]
■34027 / 2階層)  Re[2]: 文字列構造体のListのソート
□投稿者/ あおぞら 一般人(2回)-(2018/11/13(Tue) 15:21:34)
  • アイコンNo34026に返信(魔界の仮面弁士さんの記事)
    > ■No34025に返信(あおぞらさんの記事)
    >>文字列構造体のListのソートがしたいのですが、うまくいきません。
    > 文字列ソートですので、並び順は
    >  "2", "12", "123", "234"
    > ではなく、
    >  "12", "123", "2", "234"
    > になりますが、そこは大丈夫でしょうか。
    >
    >
    >>oderには1〜9と無視するデータを表す0が格納されており、
    > oder は int や char ではなく string なのですよね。
    >
    > ということは 0,1〜9 ではなく、"0","1"〜"9" の間違いであろうかと思いますが、
    > それ以外の値たとえば "" や null や "0xA" などは入らないという前提でよろしいでしょうか。
    >
    > 20 レコードのうち、orer 値が同じ値だった場合の並び順は何に従うのでしょうか。
    > List<> の格納順を維持するべきなのか、それともフィールドの内容で判断するのか、
    > 質問内容からははっきりしません。
    >
    > また、order が "0" だった場合、「そのデータは存在しないものとして、ソート結果から取り除く」のでしょうか。
    > それとも "0" なデータは「どうせ無視されるので、ソート結果の何番目にあっても気にしない」のでしょうか。
    >
    >
    >
    >>どうしたらoder順にデータを取り得だせるでしょうか。
    > orderby で。

    文字列で格納してありますが、数値として、(〇1>2>3・・・×1>12>2)ソートしたいのでInt.Parseを使っています。

    oder順で並べるときは20レコードのうち9レコードしか使わないので、oderが0の場合は検索結果に含めない、もしくは並べ替えができたらFor文で頭9回回すということを考えて後ろにつける、のどちらかがいいと考えています。

    orderby int.Parse(num.oder) を追加したのですが、Message = "入力文字列の形式が正しくありません。"とデバッガで怒られます。

違反を報告
[ 親 34025 / □ Tree ] 返信 削除キー/

▲[ 34027 ] / ▼[ 34029 ] ▼[ 34030 ]
■34028 / 3階層)  Re[3]: 文字列構造体のListのソート
□投稿者/ 魔界の仮面弁士 大御所(1163回)-(2018/11/13(Tue) 15:35:11)
  • アイコン# 引用は適切に。全文引用は避けましょう。

    No34027に返信(あおぞらさんの記事)
    >>> public List<Items> itemaList = new List<Items>();
    > 文字列で格納してありますが、数値として、(〇1>2>3・・・×1>12>2)ソートしたいのでInt.Parseを使っています。
    itemaList ではなく itemList
    Int.Parse ではなく int.Parse ですね。

    数値扱いしたいのなら、Items クラスに
     public int Order { get { return int.Parse(oder); } }
    を付与しておくという手もありますね。

    しかし oder に関して言えば、"0", "1"〜"9" しかないなら、
    int にする必要は無いようにも思えます。


    > oderが0の場合は検索結果に含めない
    それは
     itemList.Where(o => o.oder != "0")
    で良いかと。


    > oder順で並べるときは20レコードのうち9レコードしか使わないので、
    oder の値が "1"〜"9" のものは同時には存在せず、
    残り 11 レコードの oder は、すべて "0" ということですね。
    (もしかしたら、20 レコードすべてが "0" の可能性もあるかもしれませんが)

    もし、oder の値が競合することがあり、その場合は List<> 順を維持したいなら、

     var r1 = itemList.Where(o => o.oder != "0")
      .Select((item, index) => new { item, index })
      .OrderBy(o => o.item.oder).ThenBy(o => o.index)
      .Select(o => o.item);

    などと記述することが出来ます。


    > orderby int.Parse(num.oder) を追加したのですが、
    oder が競合しない "1"〜"9" ということなので、int.Parse も不要で

    var q = from o in itemList where o.oder != "0" orderby o.oder select o;

    かな。
違反を報告
[ 親 34025 / □ Tree ] 返信 削除キー/

▲[ 34028 ] / 返信無し
■34029 / 4階層)  Re[4]: 文字列構造体のListのソート
□投稿者/ 魔界の仮面弁士 大御所(1164回)-(2018/11/13(Tue) 15:43:13)
  • アイコンNo34028に追記(魔界の仮面弁士の記事)
    >> orderby int.Parse(num.oder) を追加したのですが、
    > oder が競合しない "1"〜"9" ということなので、int.Parse も不要で
    > var q = from o in itemList where o.oder != "0" orderby o.oder select o;
    > かな。

    おまけ。"10" 以降の値もあるなら、int.Parse 付きでこう書きます。

    var r = from o in itemList
        let oder = int.Parse(o.oder)
        where oder != 0
        orderby oder
        select o;


    >> orderby int.Parse(num.oder) を追加したのですが、Message = "入力文字列の形式が正しくありません。"とデバッガで怒られます。

    C# のクエリ構文では、orderby 句の後に select 句が必須です。
    (メソッド構文の場合は、OrderBy 拡張メソッドで終わっても良いですが)

    VB は Order By の後に Select を書かずとも済むのですけれどね。
違反を報告
[ 親 34025 / □ Tree ] 返信 削除キー/

▲[ 34028 ] / ▼[ 34033 ]
■34030 / 4階層)  Re[4]: 文字列構造体のListのソート
□投稿者/ あおぞら 一般人(4回)-(2018/11/14(Wed) 10:28:04)
  • アイコンNo34028に返信(魔界の仮面弁士さんの記事)
    var tes = from o in itemList where o.oder != "" orderby o.oder select o;
      for (var w = 0; w < 9; w++) { itemList_o[w] = tes.ElementAt(w); }
    とすることでやりたいことができました。
    ありがとうございました!(不要データは0が入っているというのは勘違いでnullだったのでコードも変更しています。)
解決み!
違反を報告
[ 親 34025 / □ Tree ] 返信 削除キー/

▲[ 34030 ] / 返信無し
■34033 / 5階層)  Re[5]: 文字列構造体のListのソート
□投稿者/ 魔界の仮面弁士 大御所(1167回)-(2018/11/14(Wed) 11:06:54)
  • アイコンNo34030に返信(あおぞらさんの記事)
    > (不要データは0が入っているというのは勘違いでnullだったのでコードも変更しています。)

    ならば where o.oder != "" ではなく、o.oder != null なのでは。
    あるいは、where !string.IsNullOrEmpty(o.oder) とか。


    > var tes = from o in itemList where o.oder != "" orderby o.oder select o;
    >   for (var w = 0; w < 9; w++) { itemList_o[w] = tes.ElementAt(w); }
    > とすることでやりたいことができました。
    設定値が "1"〜"9" ではなく、"1"〜"7" だった場合に備えて、
    ElementAt よりも ElementAtOrDefault の方が良いと思います。


    あるいは、常に "1"〜"9" が一意に存在することが保証されているのなら、
    そもそもループで詰め替えず、
     Items[] itemArray_out = tes.ToArray();
     List<Items> itemList_out = tes.ToList();
    だけで済ませる手もあります。(インスタンス管理次第ですが)

    # 解決済みチェックは付けたままにしておきます。
解決み!
違反を報告
[ 親 34025 / □ Tree ] 返信 削除キー/


Mode/  Pass/


- Child Tree -