Имя: Пароль:
1C
1С v8
Массив строк преобразовать в 1 строку.
0 ParinovS
 
02.05.12
18:36
Доброго времени суток! Задался вопросом, есть ли какая то стандартная функция, которая преобразует массив строк в 1 строку, типа:

строка 1;
строка 2;
строка 3;

а надо

строка1, строка2, строка3.

Хотелось бы узнать есть ли какая нить стандартная функция, или нет?!

П.С. конструкция

Для каждого Значение Из Массив Цикл
Строка = Строка + Значение;
КонецЦикла;

не нравится:)
1 Wobland
 
02.05.12
18:37
нет
2 Fragster
 
гуру
02.05.12
18:38
если массив только из строк, то

ЗначениеИзСтрокиВнутр("{""#"",51e7a0d2-530b-11d4-b98a-008048da3034,{0,{""S"",""" + СтрЗаменить(СтрЗаменить(Строка, """", """"""), Разделитель, """},{""S"",""") + """}}}")
3 Fragster
 
гуру
02.05.12
18:39
(2)+ а, попутал, это пилит строку
4 Fragster
 
гуру
02.05.12
18:40
(3)+ но в обратную сторону клеит достаточно быстро, ну а вообще - извратится можно
5 gavrikprog
 
02.05.12
18:48
(0)
есть вопрос на засыпку...
а для чего ?

кода на 5 строчек
6 Kreont
 
02.05.12
18:51
Функция Склейка(Строка1, Строка2, Строка3="", Строка4="", и т.д.)
Возврат Строка1+Строка2+Строка3+Строка4+ и т.д. аналогично;
7 Wobland
 
02.05.12
18:57
(6) на входе массив
8 ParinovS
 
02.05.12
18:58
Оооо... Скока тут извращенцев)))
вопрос заключается в быстродействии))) Я циклы не люблю просто) А если использовать стандартную конструкцию, то получается цикл в цикле)) Ну ладно, думаю цикл на массиву строк сильной нагрузки не даст... Потому как размерность массива может быть большая.
9 Kreont
 
02.05.12
18:59
(7) точно, так чем
"конструкция

Для каждого Значение Из Массив Цикл
Строка = Строка + Значение;
КонецЦикла;

не нравится" ? :)
10 Wobland
 
02.05.12
19:05
а ещё склейку можно делать в том месте, где всё пишется в массив, наверное
11 ParinovS
 
02.05.12
19:08
У меня идет обработка результата запроса. Может обрабатываться порядка 100 - 200 элементов. Все это дело выводится в ТД. У каждого элемента есть ТЧ (даже целых три), в этих ТЧ хранится грубо говоря набор строк (пусть будет "1", "2", "3"... не буду в даваться в подробности что они значат) В Каждой ТЧ тоже по 6-50 элементов. Надо чтобы список из ТЧ выводился в строку (например, "1, 2, 3, 4, ..... n") и строка выводилась в ТД. Содержимое ТЧ я загнал в массив. Т.к. думаю, что массив быстрее всего обрабатывается. Но цикл все равно придется применить.

Массив = ВыборкаДетальныеЗаписи.Ссылка.ТЧ.Выгрузить().ВыгрузитьКолонку("Номер");

ну и собственно переживал по поводу производительности :)
12 ParinovS
 
02.05.12
19:09
Сорри за код, надо так:
Массив = ВыборкаДетальныеЗаписи.Ссылка.ТЧ.ВыгрузитьКолонку("Номер");
13 Fragster
 
гуру
02.05.12
19:50
ТМП = ЗначениеВСтрокуВнутр(Массив);
ТМП = СтрЗаменить(ТМП,"""},"+Символы.ПС+"{""S"",""", Разделитель);
ТМП = Сред(ТМП,54,СтрДлина(ТМП)-59);
ТМП = СтрЗаменить(ТМП,"""""","""");
Возврат ТМП;

Возможны баги :)
заодно проверьте, как оно себя ведет на больших массивах по сравнению с циклом по производительности
14 Fragster
 
гуру
02.05.12
20:05
о, нашел багу
15 Fragster
 
гуру
02.05.12
20:08
как-то так:

ТМП = ЗначениеВСтрокуВнутр(Массив);
ТМП = СтрЗаменить(ТМП,"""},"+Символы.ПС+"{""S"",""", Разделитель);
ДопДлина=СтрДлина(Формат(Массив.Количество(),"ЧГ="));
ТМП = Сред(ТМП,53+ДопДлина);
ТМП = Лев(ТМП,СтрДлина(ТМП)-6);
ТМП = СтрЗаменить(ТМП,"""""","""");
Возврат ТМП;
16 Fragster
 
гуру
02.05.12
20:16
ГСЧ = Новый ГенераторСлучайныхЧисел;

мЯваСкрипт = Новый COMОбъект("MSScriptControl.ScriptControl");
мЯваСкрипт.Language = "javascript";

Массив = Новый Массив;
Для Сч = 1 по 50000 Цикл
   Массив.Добавить(Строка(ГСЧ.СлучайноеЧисло(0,100)));
КонецЦикла;

Разделитель = "+";

Т = мЯваСкрипт.Eval("(new Date()).valueOf()");
ТМП1 = ЗначениеВСтрокуВнутр(Массив);
ТМП1 = СтрЗаменить(ТМП1,"""},"+Символы.ПС+"{""S"",""", Разделитель);
ДопДлина = СтрДлина(Формат(Массив.Количество(),"ЧГ="));
ТМП1 = Сред(ТМП1,53 + ДопДлина);
ТМП1 = ЛЕВ(ТМП1,СтрДлина(ТМП1)- 6);
ТМП1 = СтрЗаменить(ТМП1,"""""","""");
Вр1 = (мЯваСкрипт.Eval("(new Date()).valueOf()")-Т);
Сообщить("Способ 1 "+ Вр1+"мс");

Т = мЯваСкрипт.Eval("(new Date()).valueOf()");
ТМП2 = "";
Для Сч = 0 По Массив.Количество()-1 Цикл
   ТМП2 = ТМП2 + ?(Сч = 0,"",Разделитель) + Массив[Сч];
КонецЦикла;
Вр2 = (мЯваСкрипт.Eval("(new Date()).valueOf()")-Т);
Сообщить("Способ 2 "+ Вр2+"мс");
Сообщить("В "+ Цел(Вр2/Вр1) +" раз быстрее");

Сообщить(ТМП1 = ТМП2);

Итог:
Способ 1 79мс
Способ 2 2 843мс
В 35 раз быстрее
истина
17 Fragster
 
гуру
02.05.12
20:18
Кстати, если элеметнов в массиве больше 50000 и длина элемента > 4, то способ два - не работает почему-то
18 Fragster
 
гуру
02.05.12
20:18
а, не, работает, но очень медленно
19 hhhh
 
02.05.12
21:30
(12) ну можно ведь нормально переписать запрос, чем так зверски над собой изващаться.
20 ILM
 
гуру
02.05.12
21:48
Долго думал? Но потом сделали в регистре сведений связки строк.
21 Vahe
 
02.05.12
22:04
что мешает переписать запрос?
22 aleks-id
 
02.05.12
22:15
можно в скрипт на васике передать массив строк и сделать Join
но писать код лень :)
23 hhhh
 
02.05.12
23:15
(22) но это же внутри офигенного цикла будет. То есть васик будет вызываться 100000 раз.
24 IKSparrow
 
03.05.12
00:27
Запросом!
25 orefkov
 
03.05.12
01:50
(23)
Зачем 100000 раз - один раз передал весь массив и усе.
26 orefkov
 
03.05.12
01:59
Вот так примерно:

Скрипт = Новый COMОбъект("MSScriptControl.ScriptControl");
Скрипт.Language="JScript";
Скрипт.AddCode("function join(ar, delim){return new VBArray(ar).toArray().join(delim)}");
с = Скрипт.CodeObject.join(Новый COMSafeArray(массивСтрок, "VT_VARIANT"), ",");
27 Fragster
 
гуру
03.05.12
11:48
(26) преобразование в ком массив тупит:

ГСЧ = Новый ГенераторСлучайныхЧисел;

мЯваСкрипт = Новый COMОбъект("MSScriptControl.ScriptControl");
мЯваСкрипт.Language = "javascript";

Массив = Новый Массив;
Для Сч = 1 по 10000 Цикл
   Массив.Добавить(Строка(ГСЧ.СлучайноеЧисло(100000000,999999999)));
КонецЦикла;

Разделитель = "+";

Т = мЯваСкрипт.Eval("(new Date()).valueOf()");
ТМП1 = ЗначениеВСтрокуВнутр(Массив);
ТМП1 = СтрЗаменить(ТМП1,"""},"+Символы.ПС+"{""S"",""", Разделитель);
ДопДлина = СтрДлина(Формат(Массив.Количество(),"ЧГ="));
ТМП1 = Сред(ТМП1,53 + ДопДлина);
ТМП1 = ЛЕВ(ТМП1,СтрДлина(ТМП1)- 6);
ТМП1 = СтрЗаменить(ТМП1,"""""","""");
Вр1 = (мЯваСкрипт.Eval("(new Date()).valueOf()")-Т);
Сообщить("Способ 1 "+ Вр1+"мс");

Т = мЯваСкрипт.Eval("(new Date()).valueOf()");
ТМП2 = "";
Для Сч = 0 По Массив.Количество()-1 Цикл
   ТМП2 = ТМП2 + ?(Сч = 0,"",Разделитель) + Массив[Сч];
КонецЦикла;
Вр2 = (мЯваСкрипт.Eval("(new Date()).valueOf()")-Т);
Сообщить("Способ 2 "+ Вр2+"мс");

Скрипт = Новый COMОбъект("MSScriptControl.ScriptControl");
Скрипт.Language="JScript";
Скрипт.AddCode("function join(ar, delim){return new VBArray(ar).toArray().join(delim)}");

Т = мЯваСкрипт.Eval("(new Date()).valueOf()");
ТМП3 = Скрипт.CodeObject.join(Новый COMSafeArray(массив, "VT_VARIANT"), Разделитель);
Вр3 = (мЯваСкрипт.Eval("(new Date()).valueOf()")-Т);
Сообщить("Способ 3 "+ Вр3+"мс");

Сообщить(ТМП1 = ТМП2);
Сообщить(ТМП2 = ТМП3);


Выводит
Способ 1 16мс
Способ 2 500мс
Способ 3 63мс
истина
истина
28 Кирпич
 
03.05.12
12:37
Можно еще через ЧтениеТекста и ЗаписьТекста
29 orefkov
 
03.05.12
12:46
(27)
А теперь представь, что в массиве есть не строковые значения.
30 Fragster
 
гуру
03.05.12
12:47
(29) "Доброго времени суток! Задался вопросом, есть ли какая то стандартная функция, которая преобразует массив строк в 1 строку"
31 Fragster
 
гуру
03.05.12
12:49
а вариант с ком массивом вообще падает
32 izekia
 
03.05.12
12:51
(28) там такой же алгоритм как и при тупом сложении
33 Кирпич
 
03.05.12
13:41
(32) Да нет, другой. И работает быстрее в несколько раз.
34 izekia
 
03.05.12
13:46
(33) я в каком-то из релизов тестировал, в надежде что это вроде шарповского аналога, но прироста в скорости не увидел
35 Кирпич
 
03.05.12
13:55
(34) Попробовал. что в несколько раз, я наврал. в два раза только быстрее.
36 izekia
 
03.05.12
13:56
(35) понял, спасибо за информацию
37 Fragster
 
гуру
03.05.12
14:15
интересное наблюдение про способ с циклом (память не растет, в районе 100 метров воркинг сет, в районе 300 виртуальная):

ГСЧ = Новый ГенераторСлучайныхЧисел;

мЯваСкрипт = Новый COMОбъект("MSScriptControl.ScriptControl");
мЯваСкрипт.Language = "javascript";

Массив = Новый Массив;

Для СчТ = 1 по 100 Цикл
   Для Сч = 1 по 5000 Цикл
       Массив.Добавить(Строка(ГСЧ.СлучайноеЧисло(100000000,999999999)));
   КонецЦикла;
   Разделитель = "+";
   
   Т = мЯваСкрипт.Eval("(new Date()).valueOf()");
   ТМП2 = "";
   Для Сч = 0 По Массив.Количество()-1 Цикл
       ТМП2 = ТМП2 + ?(Сч = 0,"",Разделитель) + Массив[Сч];
   КонецЦикла;
   
   Вр2 = (мЯваСкрипт.Eval("(new Date()).valueOf()")-Т);
   Сообщить("Обработка " + Символы.Таб+ Массив.Количество() +" элементов "+ Символы.Таб+ Вр2 +Символы.Таб+"мс");
   Если ВР2 > 60000 Тогда Прервать КонецЕсли;
       
КонецЦикла;


Обработка    5 000 элементов    156    мс
Обработка    10 000 элементов    500    мс
Обработка    15 000 элементов    1 219    мс
Обработка    20 000 элементов    3 954    мс
Обработка    25 000 элементов    12 719    мс
Обработка    30 000 элементов    26 906    мс
Обработка    35 000 элементов    43 703    мс
Обработка    40 000 элементов    62 828    мс
38 Кирпич
 
03.05.12
14:18
?(Сч = 0,"",Разделитель)

эта фигня жрет половину времени
39 Fragster
 
гуру
03.05.12
14:24
(38) эээ... в геометрической прогрессии увеличивая время? ну, можно так (в пределах погрешности):

   ТМП2 = "";
   Для Сч = 0 По Массив.Количество()-1 Цикл
       ТМП2 = ТМП2 + Разделитель + Массив[Сч];
   КонецЦикла;
   ТМП2 = Сред(Тмп2, СтрДлина(Разделитель)+1);

Обработка    5000     элементов    140    мс
Обработка    10000     элементов    516    мс
Обработка    15000     элементов    3531    мс
Обработка    20000     элементов    4359    мс
Обработка    25000     элементов    17453    мс
Обработка    30000     элементов    32313    мс
Обработка    35000     элементов    44828    мс
Обработка    40000     элементов    65391    мс
40 Fragster
 
гуру
03.05.12
14:34
1%  Значение = Массив[Сч];
92% ТМП2 = ТМП2 + Разделитель + Значение;
41 Fragster
 
гуру
03.05.12
15:18
однако же вот такое извращение:
       ТМП1 = "";
       ТМП2 = "";
       КолСтрок = 10;
       Для Сч = 0 По Массив.Количество()-1 Цикл
           Значение = Массив[Сч];
           Если (Сч+1) % КолСтрок <> 0 Тогда
               ТМП1 = ТМП1 + Разделитель + Значение;
           Иначе
               ТМП1 = Сред(ТМП1, СтрДлина(Разделитель)+1);
               ТМП2 = ТМП2 + Разделитель + ТМП1;
               ТМП1 = "";
           КонецЕсли
       КонецЦикла;

сокращает с 30ти секунд до 4х секунд обработку 30000 элементов массива (и до 2,5 секунд, если КолСтрок = 100).
получается, что 1с медленно работает с длинными строками :(
42 НЕА123
 
03.05.12
15:26
(39)

на 100 000 элементах работал 3минуты.


вот так

ТекстДок = Новый ТекстовыйДокумент;
Для каждого Эл Из Массив Цикл
   ТекстДок.ДобавитьСтроку(Эл);
КонецЦикла;


7 секунд.
43 НЕА123
 
03.05.12
15:28
(42)+
НужнаяСтрока = ТекстДок.ПолучитьТекст();
44 fisher
 
03.05.12
15:54
(41) Быстродействие элементарных операций в 1С - это отдельная смешная тема. На 8-ке математика даже несколько медленнее стала, чем в 7.7
Просто на фоне операций с БД это всё - капля в море. Поэтому в 1С этим никогда и не заморачивались.
45 Fragster
 
гуру
03.05.12
16:42
(42) так можно потерять данные, если у тебя в элементах массива есть многострочные элементы, а разделитель - не символы.СП
46 Fragster
 
гуру
03.05.12
16:52
(42) вариант (41) на 100000 элементах (с КолСтрок = 100) отработал за 8 секунд, при том что без изврата срубил на 5 минутах (т.е. машина слабее). вариант (27).1 отработал за 1 секунду...