簡體   English   中英

用Linq將字符串拆分為對象?

[英]String split to object with Linq?

鑒於:

    class T
    {
        public string A { get; set; }
        public string B { get; set; }
    }

    string s = "A|B";

有沒有辦法在|上拆分s? 並返回“內聯” T對象? 我知道我可以做類似的事情:

s.Select(x => { string[] arr = s.Split(); return new T() { A = arr[0], B = arr[1] };

但是我想知道是否有一些晦澀的linq事情可以“內聯”執行而不聲明數組並在select內部拆分。 以下方面的內容:

s.Split().Select(x => new T() { A = x[0], B = x[1] });

顯然,這會給您一個編譯器錯誤,但是您知道了...有沒有辦法做到這一點?

如果要一行完成,請確保:

var s = "A|B";
var t = new T{ A = s.Split('|')[0], B = s.Split('|')[1] };

但是很明顯,它兩次使用Split ,看起來很糟糕。

這可能表明您需要一種方法:

private static T ParseT(string s) {
    // do the conversion *properly* here
}

然后,您可以調用它:

ParseT("A|B")

或者,添加顯式(推薦)或隱式轉換:

public static explicit operator T(string s) {
    // do the conversion *properly* here
}

如果使用查詢語法,則可以執行以下操作:

var strings=new string[] { "A|B","C|D"};
var query= from s in strings
           let x=s.Split('|')
           select new T{ A = x[0], B = x[1] };

更新資料

如果"A|B"是數據源,我不建議為此使用Linq,則可以執行以下操作:

    var arr= str.Split('|'); 
    var instance=new T{A = arr[0],B=arr[1]};

或者在構造函數中執行與@James在其答案中建議的相同操作。

它實際上並沒有比您最初擁有的更好,但是這是一種方法(如果s是IEnumerable<string>

s.Select(x=>x.Split('|')).Select(x=>new T{A=x[0],B=x[1]});

如果s是單個字符串,則可以這樣做:

new List<string>{s}  // Now List<string> with 1 string in the list
.Select(x=>x.Split('|')) // now IEnumerable<string[]> with 1 string array in it
.Select(x=>new T{A=x[0],B=x[1]}) // now IEnumerable<T> with 1 T in it
.First(); // Now just T

為什么要對抗實際的語言概念:

void Main()
{
    var strs = new List<string> { "A|B", "CCC|DD", "E|FFF"};

    var Ts = strs.Select(s =>s.ToT() );
    Ts.Dump();
}

static class Ext
{
    static public T ToT(this string str)
    {
        return new T(str);
    }
}

public class T
{
    public string A { get; set; }
    public string B { get; set; }

    public T(string str)
    {
        var arr= str.Split('|'); 
        A = arr[0];
        B = arr[1];
    }
}

注意我不建議這樣做,這更有趣。

public static T CreateLinq(string s)
        {
            return s.Aggregate((a: new StringBuilder(), b: new StringBuilder(), c: false),
                (acc, c) => (a: (!acc.c && c != '|' ? acc.a.Append(c) : acc.a),
                             b: (acc.c && c != '|' ? acc.b.Append(c) : acc.b),
                             c: acc.c || c == '|'),
                acc => new T { A = acc.a.ToString(), B = acc.b.ToString() });
        }

而且性能還不如乍看之下那么糟糕。

public class T
        {
            public string A { get; set; }
            public string B { get; set; }
        };

        static void Main(string[] args)
        {
            var s1 = Enumerable.Range(0, 1000000).Aggregate(new StringBuilder(), (acc, i) => acc.Append("A")).ToString();
            var s2 = Enumerable.Range(0, 1000000).Aggregate(new StringBuilder(), (acc, i) => acc.Append("B")).ToString();
            var text =$"{s1}|{s2}";

            for (int i = 0; i < 5; i++)
            {
                Stopwatch sw = new Stopwatch();
                Console.WriteLine("Start");
                sw.Start();
                var t1 = CreateT(text);
                sw.Stop();
                Console.WriteLine(sw.ElapsedMilliseconds);
                sw.Reset();

                sw.Start();
                var t2 = CreateLinq(text);
                sw.Stop();
                Console.WriteLine(sw.ElapsedMilliseconds);
                sw.Reset();
            }
            Console.ReadLine();
        }

        public static T CreateLinq(string s)
        {
            return s.Aggregate((a: new StringBuilder(), b: new StringBuilder(), c: false),
                (acc, c) => (a: (!acc.c && c != '|' ? acc.a.Append(c) : acc.a),
                             b: (acc.c && c != '|' ? acc.b.Append(c) : acc.b),
                             c: acc.c || c == '|'),
                acc => new T { A = acc.a.ToString(), B = acc.b.ToString() });
        }

        public static T CreateT(string s)
        {
            var split = s.Split('|');
            return new T { A = split[0], B = split[1] };
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM