|
Массив строк преобразовать в 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 секунду...
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |