Что нового

Как двумерный массив отправить в файл?

ViktorSPB

Новичок
Сообщения
109
Репутация
0
Добрый день.
Пишу подпрограмму, которая должна данные из двумерного массива быстро записать в файл.
Вожусь с циклами и понимаю, что все должно быть проще. Если кто знает, как это сделать быстро и красиво, подскажите, пожалуйста..
Погуглил нашел http://msdn.microsoft.com/ru-ru/library/3det53xh.aspx . Как прикрутить не понимаю пока, но думаю, что может помочь.. В UDF функции работают с одномерным массивом, не подходят, да и в них циклами обработка идет.. А у меня строк много.
Подскажите, пожалуйста, как решить вопрос?
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
А если использовать __ArrayToString (есть универсальная)
а затем текст записать в файл ?

Я уже где-то приводил :Array(1D-2D).au3



Добавлено:
Сообщение автоматически объединено:

Хотя там тоже с циклом
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
А вообще реально массив записать без его перебора? :-\
IMHO без циклов не обойтись.
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Garrett [?]
А вообще реально массив записать без его перебора?
undecided.gif
IMHO без циклов не обойтись.

Наверняка нет :laugh:
 
Автор
V

ViktorSPB

Новичок
Сообщения
109
Репутация
0
gregaz,
пробовал _FileWriteFromArray каждый элемент ОДНОМЕРНОГО массива кидает через разделитель. Мне надо двумерный.
Вот Сейчас и пишу как раз на базе того, что Вы написали.. Вытаскиваю каждый элемент, добавляю сначала запятые, в конце разделитель, далее в файл. Вот и приходится перебирать 100 тыс. строк.. А по сути надо к определ. Функцию, которая так же как и _FileWriteFromArray только с двумя разделителями. между ячейками в строке и самими строками. Ведь есть в программах возможности экспорта в текстовик, ну не перебирают же они все там попунктно.. попунктно.. слово то какое)
Еще есть похожая тема - http://autoit-script.ru/index.php/topic,2627.15.html
Посмотрел в msdn методы, подходяшего не нашел..
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
ViktorSPB
я не понимаю, с чего ты взял что _FileWriteFromArray не в цикле делает это. Там тоже перебирается каждый элемент и пишется в файл. На самом деле узким местом в такой операции - это запись данных на диск. Я не думал, что эта функция делает это настолько глупо. То есть пишет поэлементно. Я бы, например, сначала построил строку нужного формата не превышающего допустимый размер, и записал его. Уверен, это ускорит работу. По поводу двумерных или каких бы то ни было массивов размерностью выше первого - это все абстракция для улучшения восприятия человеком. В памяти же компьютера это все одномерные массивы - стеки. Поэтому цикл по элементам и никак иначе. Но опять же, писать как можно реже и большими кусками
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Быстрее вряд ли получится.

Код:
#Include <Array.au3>

Dim $Array[4][2] = [['A1', 'A2'], ['B1', 'B2'], ['C1', 'C2'], ['D1', 'D2']]

_ArrayDisplay($Array)

; Записываем

Dim $Col[2] = ['', '']

For $i = 0 To 1
	For $j = 0 To UBound($Array) - 1
		$Col[$i] &= $Array[$j][$i] & ChrW(160)
	Next
	$Col[$i] = StringTrimRight($Col[$i], 1)
Next

ConsoleWrite($Col[0] & @CR)
ConsoleWrite($Col[1] & @CR)

$Array = 0

; Загружаем

$Col0 = StringSplit($Col[0], ChrW(160), 2)
$Col1 = StringSplit($Col[1], ChrW(160), 2)

Dim $Array[UBound($Col0)][2]

For $i = 0 To UBound($Array) - 1
	$Array[$i][0] = $Col0[$i]
	$Array[$i][1] = $Col1[$i]
Next

_ArrayDisplay($Array)
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
ViktorSPB
ещё

Код:
#include <Array.au3>

$a = StringRegExp('qwertyuiop[]asdfghjkl;zxcvbnmйцукенгшщзхъфывапролджэ\ячсмитьбю.1234567890','(.{3})',3)
Dim $b[UBound($a)][3]
For $i = 0 to UBound($b)-1
	$tmp = StringSplit($a[$i], '')
	$b[$i][0]=$tmp[1]
	$b[$i][1]=$tmp[2]
	$b[$i][2]=$tmp[3]
Next
_ArrayDisplay($b, 'массив сейчас')

; конвертируем массив в текст
; $sep1='#'
$sep1='}—•—{' ; разделитель не должен находится в тексте/массиве
$sep2=@CRLF ; перенос строки в качестве разделителя создаёт читабельный текст
$L1=StringLen($sep1) ; определяем длинну разделителя для обрезки в конце строки
$L2=StringLen($sep2) ; определяем длинну разделителя для обрезки в конце текста
$txt='' ; некая переменная, которая будет содержать готовые данные для записи в файл
For $i = 0 to UBound($b)-1
	For $j = 0 to 2 ; число колонок нам известно - 3
		$txt&=$b[$i][$j]&$sep1 ; присоединяем очередную ячеку и $sep1 - разделитель
	Next
	$txt=StringTrimRight($txt, $L1) ; обрезаем конечный разделитель строки
	$txt&=$sep2 ; добавляем разделитель строки
Next
$txt=StringTrimRight($txt, $L2) ; обрезаем конечный разделитель

; записываем в файл
$file = FileOpen(@ScriptDir&'\file.txt',2)
FileWrite($file, $txt)
FileClose($file)

MsgBox(0, 'Смотрим что получилось', $txt)

; !i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i

; читаем файл
$text = FileRead(@ScriptDir&'\file.txt')
$aText = StringSplit($text, $sep2, 1)
; Dim $new[$aText[0]+1][3] =[[$aText[0]]] ; можно с количеством в первой ячейке
Dim $new[$aText[0]][3] ; объявляем массив по размеру прочитанного

For $i = 0 to $aText[0]-1
	$tmp = StringSplit($aText[$i+1], $sep1, 1)
	$new[$i][0]=$tmp[1]
	$new[$i][1]=$tmp[2]
	$new[$i][2]=$tmp[3]
Next
_ArrayDisplay($new, 'прочитаный массив')
 
Автор
V

ViktorSPB

Новичок
Сообщения
109
Репутация
0
Да, я так и не нашел ничего более подходящего, чем поэлементная обработка. Благо с массивами AutoIt быстро работает. В будущем, когда научусь, напишу библиотеку, DDL, пусть счетает. Я сейчас так и сделал, как вы написали, принцип тотже, небольшие нюансы только.. А записывать, конечно один раз, после формирования строки, все через текст. В принципе, массив в 200 000 строк, например, около 0.5 сек. обрабатывается вместе с записью на винт. Сама запись около 25 мс. Вполне приемлемые значения пока для меня.
У меня еще вопрос, подскажите мне вот что. Как счетаете, что быстрее будет обрабатываться, строка с разделителями через регулярные выражения, или массив? Мне пока ближе массив, потому что регулярные выражения мне пока даются с трудом. Хоть и почитал темы тут... Вроде и тупым себя сильно не считаю, но как-то не могу настроится на волну авторов. Нашел другой рессурс с описанием, там буду разбираться.
И все же, на будущее, чем лучше (быстрее) обрабатывать большое количетсво данных? Я пока архитектуру не представляю..
[box title=OffTop]
to Yashied. sc2 :laugh:
[/box]
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
ViktorSPB
Конечно регулярное выражение к тексту сработает быстрее чем массив по-элементно, ведь потребуется функции вызывать при каждой итерации. Это уже второй вопрос.
 
Верх