Як я магу падзяліць набор радкоў на складнікі іх сімвалы ў C #?

Што гэта лепшы спосаб, каб аддзяліць асобныя сімвалы ў масіў радкоў strArr у масіў гэтых знакаў charArr , як паказана ніжэй?

string[] strArr = { "123", "456", "789" };
char[] chrArr = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };

Гэта тое, што я цяпер раблю, але я не думаю, што гэта вельмі элегантна:

int characterCount = 0;

for (int i = 0; i < strArr.Length; i++)
{
    characterCount += strArr[i].Length;
}

int indexCount = 0;
char[] chrArr = new char[characterCount];

for (int i = 0; i < strArr.Length; i++)
{
    for (int j = 0; j < strArr[i].Length; j++)
    {
        chrArr[indexCount] = strArr[i][j];
        indexCount++;
    }
}
15

6 адказы

Ну, просты шлях будзе такім:

char[] chrArr = string.Join(string.Empty, strArr).ToCharArray();

Для таго, каб пераканацца, што няма ніякай блытаніны над тэхнічнымі характарыстыкамі тут, вось кароткая праграма для тэставання ў LINQPad (не забудзьцеся ўключыць аптымізацыі ў ніжні правы кут):

static string[] strArr = { "123", "456", "789" };

void Main()
{
    const int iterations = 10000000;//10 million

   //Warm up JITter
    StringJoin();
    LINQSelectMany();
    LINQ();

    Stopwatch sw = Stopwatch.StartNew();
    for (int index = 0; index < iterations; index++)
        StringJoin();
    sw.Stop();
    sw.ElapsedMilliseconds.Dump("String.Join");

    sw.Restart();
    for (int index = 0; index < iterations; index++)
        LINQSelectMany();
    sw.Stop();
    sw.ElapsedMilliseconds.Dump("LINQ SelectMany");

    sw.Restart();
    for (int index = 0; index < iterations; index++)
        LINQ();
    sw.Stop();
    sw.ElapsedMilliseconds.Dump("LINQ");
}

public static void StringJoin()
{
    char[] c = string.Join(string.Empty, strArr).ToCharArray();
}

public static void LINQSelectMany()
{
    char[] c = strArr.SelectMany(s => s).ToArray();
}

public static void LINQ()
{
    var characters = (from s in strArr
                      from c in s
                      select c).ToArray();

}

Вы можаце спампаваць гэты LINQPad сцэнар тут , калі вы хочаце, каб гуляць з ім.

Выхад (у мілісекундах):

String.Join 
765 

LINQ SelectMany 
5098 

LINQ 
5465 

(звычайнае перасцярога аб прадукцыйнасці вымярэння кода ўжываецца тут, паказваюць на памылкі, якія я зрабіў)

42
дададзена
Калі ласка, вызначыце «адпаведнае". Просты тэст прадукцыйнасці паказвае, што мая лінія звання ў SelectMany лініі з каэфіцыентам 8. Так як ні здаецца, прапануюць якія-небудзь пэўныя перавагі ў параўнанні з іншай (напрыклад, апрацоўка edgecases або лепш яшчэ шмат чаго), я б хутчэй, калі адзін я магу. Асабіста я не адчуваю, што яны моцна адрозніваюцца з пункту гледжання чытальнасці небудзь.
дададзена аўтар Lasse Vågsæther Karl, крыніца
Гэта, здаецца, сапраўды па-дурному. LINQ здаецца значна больш інтуітыўным і мэтазгодна ...
дададзена аўтар Timothy Shields, крыніца
<�Я> адпаведныя (прым.): Падыходзіць або ўласна ў дадзеных абставінах. :) - Я не кажу, што вы не мелі рацыю, я проста кажу, што «здавалася» больш інтуітыўна (або C# ідыёматычны) выкарыстоўваць LINQ. Не саромейцеся пагадзіцца, хоць.
дададзена аўтар Timothy Shields, крыніца
+1 для вымярэння прадукцыйнасці і разумных каментароў у раздзеле абмеркавання
дададзена аўтар Ilya Ivanov, крыніца
Так, радок і метады іх радковыя вельмі моцна аптымізаваныя на самай справе!
дададзена аўтар Matthew Watson, крыніца
@TimothyShields «інтуітыўны» і «адпаведнае" суб'ектыўныя. LINQSelectMany прымусіў мяне глядзець у дакументацыі, каб зразумець гэта і LINQ прымусіў мяне перачытаць яго некалькі разоў з-за якія не з'яўляюцца апісальных імёнаў зменных і таму множным з заявы трохі замежнай для мяне. З іншага боку, я адразу зразумеў StringJoin. Linq будзе больш інтуітыўным з майго пункту гледжання, калі SelectMany быў названы «Concat» (існуе, але ...) або "Давесці».
дададзена аўтар Emperor Orionii, крыніца

Я хацеў бы зрабіць:

char[] chrArr = strArr.SelectMany(s => s).ToArray();
19
дададзена
Там няма асаблівага сэнсу ў тым, «права» тут, так як прыклад кода ў пытанні вынайдзеным для гэтага канкрэтнага пытання, то, як LINQ, безумоўна, заслугоўвае ўвагі, і ў той час як будзе выкарыстоўваць радка. Join метад, калі я магу, гэты код можа нават не быць вузкім месцам, так што калі шлях LINQ з'яўляецца больш зручным для чытання іншых распрацоўнікаў, кожны свае. Я б не стаў заходзіць так далёка, каб сказаць, што метад LINQ гэта няправільна, але гэта сапраўды плаціць, каб ведаць шмат не-LINQy рамачнага кода, проста таму, што LINQ з'яўляецца «новая хваля» не азначае, што ўсе стары код дрэнны, павольна ці няправільна. Мне спадабаліся прыклады LINQ, хоць :)
дададзена аўтар Lasse Vågsæther Karl, крыніца
Я сумняваюся, што ён будзе выкарыстоўваць больш памяці. Так, ён будзе будаваць адзін радок з string.join перад пераўтварэннем у масіў сімвалаў, у той час як ToArray будзе стварыць спіс, перш чым вярнуцца ў новы масіў. Бо спіс звычайна заканчваецца з большай магутнасцю, чым на самай справе неабходна, я наіўна думаю, што метад string.join будзе пераўзыходзіць тут, але я не цвёрды спосаб вымярэння гэтага, так што я буду трымаць гэтую думку сабе :)
дададзена аўтар Lasse Vågsæther Karl, крыніца
Карацей не значыць лепш, і з пункту гледжання мінімізацыі часу, я думаю, вы павінны сапраўды зрабіць некаторыя вымярэння прадукцыйнасці, каб пераканацца, што зацвярджэнне дакладна :)
дададзена аўтар Lasse Vågsæther Karl, крыніца
@ I4V Як гэта па-дурному? Я знаходжу гэта <�б> вельмі разумны.
дададзена аўтар It'sNotALie., крыніца
@ I4V Што? Што ты маеш на ўвазе?
дададзена аўтар It'sNotALie., крыніца
Іма ісці upvote ў прадукцыйную адзін.
дададзена аўтар Jesse C. Slicer, крыніца
Я не магу паверыць, гэты адказ атрымлівае 2 upvotes і дурныя 14.
дададзена аўтар I4V, крыніца
@newStackExchangeInstance Працягвайце рабіць ...
дададзена аўтар I4V, крыніца
Я павінен прызнаць, што <�я> «дурныя адзін» </я> здзіўлены мяне з вынікамі выпрабаванняў (я зрабіў мае ўласныя тэсты таксама).
дададзена аўтар I4V, крыніца
@ LasseV.Karlsen Х так, вы не памыліліся аб правядзенні вымярэнняў. :) Памеркаваўшы, я чакаю, радок Join() хутчэй, але патрабуе больш памяці.
дададзена аўтар Matthew Watson, крыніца
@ LasseV.Karlsen Ну так ці інакш, вы мелі рацыю. ;)
дададзена аўтар Matthew Watson, крыніца
var res = strArr.SelectMany(c => c.ToCharArray()).ToArray();
7
дададзена
@EdPlunkett Ці магу я спытаць, чаму ў той час як ToCharArray не патрэбны?
дададзена аўтар I4V, крыніца
Гэта мой любімы.
дададзена аўтар Ed Plunkett, крыніца
@ I4V Добры момант. Вы маеце рацыю, і я прапусціў гэта. Мне спадабалася з-за SelectMany (), і аддалі перавагу яго іншай SelectMany() з-за «вар» замест паўкокс [].
дададзена аўтар Ed Plunkett, крыніца

LINQ на аснове версіі будзе:

var input = new string[] { "abc", "def", "ghi" };
var characters = (from s in input
                  from c in s
                  select c).ToArray();

foreach (var c in characters) Console.WriteLine(c);
3
дададзена

Гэта ў асноўным пашырэнне адказ Джэсі SLICER ст.

Проста ачысткі кода з ReSharper (калі ў вас няма гэтага ці нешта накшталт гэтага, ідзі цяпер) дае наступнае:

var characterCount = strArr.Sum(t => t.Length);

var indexCount = 0;
var chrArr = new char[characterCount];

foreach (var t1 in strArr.SelectMany(t => t))
{
    chrArr[indexCount] = t1;
    indexCount++;
}

<�Код> Еогеасп гэта проста запаўненне масіва і ўжо ёсць метад LINQ ToArray для гэтага. Тады characterCount і indexCount зусім непатрэбныя.

var chrArr = strArr.SelectMany(t => t).ToArray();
1
дададзена

паспрабаваць гэта ..

 string value="";
 string[] strArr = { "123", "456", "789" }; //Your string array.

 for(int i=0;i
0
дададзена