5

string[]のアイテムを特定の文字列の位置に従って並べ替える方法を教えてください。たとえば、次の配列を部分文字列「-」で並べ替えたいとします。

入力:{xx-c、xxxxx-b、yyy-a、mlllll-d}

期待される出力:{yyy --a、xxxxx --b、xx --c、mlllll --d}

私がこれまでに持っているのは次のとおりです。

public string[] SortByStringPos(string[] arr, string str, bool ascending)
{
    if (ascending)
    {
        var result = from s in arr
                     where s.Length >= s.IndexOf(str)
                     orderby s[s.IndexOf(str)] ascending
                     select s;

        return result.ToArray();
    }
    else
    {
        var result = from s in arr
                     where s.Length >= s.IndexOf(str)
                     orderby s[s.IndexOf(str)] descending
                     select s;

        return result.ToArray();
    }
}

誰かが私にヒントを落とすことができますか...?

4

4 に答える 4

3
orderby x=>x.Substring(x.LastIndexOf('-'))

私は推測する

したがって、通常の方法で注文する必要があります。次に、orderBy....thenByのようにこれを使用できます。

于 2012-11-16T13:56:19.163 に答える
3

パフォーマンスとデザインを向上させるために、次のものを使用することをお勧めします。

    public void SortByStringPos(string[] arr, string str, bool ascending)
    {
        Array.Sort(arr, new MyStrComparer("-", ascending));
    }

    class MyStrComparer : Comparer<string>
    {
        string delimiter;
        bool isAscending;

        public MyStrComparer(string aStr, bool ascending)
        {
            delimiter = aStr;
            isAscending = ascending;
        }

        public override int Compare(string x, string y)
        {
            var r = GetMySubstring(x).CompareTo(GetMySubstring(y));
            return isAscending ? r : -r;
        }

        string GetMySubstring(string str)
        {
            return str.IndexOf(delimiter) != -1 ? str.Substring(str.LastIndexOf(delimiter)) : string.Empty;
        }

    }

メソッドを削除して、コードのどこからでもSortByStringPos呼び出すことができArray.Sort(arr, new MyStrComparer("-", ascending));ます。

于 2012-11-16T14:01:53.410 に答える
2
static void Main()
{
    var input = new[] { "xx - c", "xx - b", "yy - a", "ml - d", };
    var delimeter = "-";
    var isAscending = true;

    var res = Sort(input, delimeter, isAscending);
}

static string[] Sort(string[] input, string delimeter, bool isAscending)
{
    var withDelimeter = input.Where(p => p.Contains(delimeter));
    var withoutDelimeter = input.Except(withDelimeter);

    Func<string, string> selector = p => p.Substring(p.IndexOf(delimeter));

    return
        (
            isAscending

                ? withDelimeter.OrderBy(selector)
                    .Concat(withoutDelimeter.OrderBy(p => p))

                : withoutDelimeter.OrderByDescending(p => p)
                    .Concat(withDelimeter.OrderByDescending(selector))
        )
        .ToArray();
}
于 2012-11-16T14:07:26.860 に答える
0

Substring文字列の最後の部分を取得するために使用します。LINQ クエリは、段階的に構築できます。これにより、コードの繰り返しが減ります (= DRY 原則、Don't Repeat Yourself):

var query = arr.Where(s => s.Contains(str));
Func<string,string> sortExpr = s => s.Substring(s.IndexOf(str));
if (ascending) {
    query = query.OrderBy(sortExpr);
} else {
    query = query.OrderByDescending(sortExpr);
}
return query.ToArray();
于 2012-11-16T14:39:33.537 に答える