<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Парсинг дерева]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=14598&amp;type=atom" />
	<updated>2019-02-25T11:21:31Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=14598</id>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132498#p132498" />
			<content type="html"><![CDATA[<p>Можно отдаться полемике и порассуждать на тему того, как это условие подталкивает к тому, что в такую структуру собирал криворукий программист, привнеся в свою БД некоторую произвольность. Что тут в пору переписать логику получения данных, иначе это грозит периодическими нестыковками, или излишними проверками для понимания того, верно ли код обращается за данными, или начальным перебором, чтобы получить &quot;карту&quot; БД и прочее...</p><p>Для &quot;Яблоки,Груши,Ананас&quot; семантически подходит быть значением в такой БД, находясь в доступе по какому-нибудь &quot;Наименования&quot;, самому быть такой ёмкостью, или не существовать вообще. И хотя, &quot;Хозяин - барин&quot; и мне с таким &quot;Хозяином&quot; &quot;детей не растить&quot;, перфекционист во мне протестует и это скорее &quot;крик души&quot;. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p>]]></content>
			<author>
				<name><![CDATA[KusochekDobra]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=33846</uri>
			</author>
			<updated>2019-02-25T11:21:31Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132498#p132498</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132492#p132492" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>KusochekDobra пишет:</cite><blockquote><p>то можно так</p></blockquote></div><p>А как тут получить строку &quot;Яблоки,Груши,Ананас&quot;? <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2019-02-25T00:46:15Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132492#p132492</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132491#p132491" />
			<content type="html"><![CDATA[<p>Если заранее известно, какую глубину считать конечной для получения значений залегающих на её уровне, то можно так:<br /></p><div class="codebox"><pre><code>
data =
(
База 1
	склад 1
		Яблоки,Груши,Ананас
		Настройки
			Размер
			Кол-во контейнеров
		Яблоки
			И тут разновидности
			в 100+ строк
		Груши
			и пошло, поехало
		Ананас
			к сожалению один, привоза не было
База 2
	склад2 
		Сливы,Киви,Апельсины
		Настройки
			Размер
			Кол-во контейнеров
)

obj := Separator_Razdelyator( StrSplit(data, &quot;`n&quot;), 3 )
MsgBox % obj[&quot;База 1&quot;, &quot;склад 1&quot;, &quot;Яблоки&quot;, 2]

ExitApp
Separator_Razdelyator(data, depth := 2) {
	obj := {}
	For i, item in data {
		item := StrReplace(item, &quot;`t&quot;, &quot;&quot;, level)
		if (!level) {
			obj[item] := {}
			itemLevel_1 := obj[item]
		} else if (level == depth) {
			itemLevel_%depth%.Push( item )
		} else {
			itemLevel_%level%[item] := level + 1 == depth ? [] : {}
			levelPlus := level + 1
			itemLevel_%levelPlus% := itemLevel_%level%[item]
		}
	} Return obj
}</code></pre></div><p>Но если значения ожидать на разных уровнях, то тогда нужно рассчитывать маску.</p>]]></content>
			<author>
				<name><![CDATA[KusochekDobra]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=33846</uri>
			</author>
			<updated>2019-02-24T23:56:08Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132491#p132491</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132490#p132490" />
			<content type="html"><![CDATA[<p>В общем, наверно идеального варианта нет, к каждому случаю какой-то свой лучше.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2019-02-24T21:53:37Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132490#p132490</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132489#p132489" />
			<content type="html"><![CDATA[<p>Ок, тогда так можно, чтобы сохранить структуру:<br /></p><div class="codebox"><pre><code>data =
(
склад 1
	Яблоки,Груши,Ананас
	Настройки
		Размер
		Кол-во контейнеров
	Яблоки
		И тут разновидности
		в 100+ строк
	Груши
		и пошло, поехало
	Ананас
		к сожалению один, привоза не было
склад2 
	Сливы,Киви,Апельсины
	Настройки
		Размер
		Кол-во контейнеров
)

obj := {}
child0 := obj
Loop, parse, data, `n, `r
{
   RegExMatch(A_LoopField, &quot;^(?&lt;indent&gt;`t*)(?&lt;text&gt;.*)&quot;, _)
   StrReplace( _indent, A_Tab, &quot;&quot;, level)
   prevLevel := level, level += 1
   if (A_Index &gt; 1) {
      if !(level &gt; prev_level)
         child%prev_prevLevel%.Push(prev_text)
      else {
         o := {}, o[prev_text] := child%prev_level% := []
         child%prev_prevLevel%.Push(o)
      }
   }
   prev_level := level, prev_prevLevel := prevLevel, prev_text := _text
}
child%prev_prevLevel%.Push(_text)</code></pre></div><p><span class="postimg"><img src="https://i.imgur.com/7Xq3SVZ.png" alt="https://i.imgur.com/7Xq3SVZ.png" /></span><br />На картинке массивы от 0, в реальности от 1.<br />Все родственные объекты на одном уровне, вне зависимости от того, строки это, или массивы.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2019-02-24T21:41:34Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132489#p132489</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132488#p132488" />
			<content type="html"><![CDATA[<p>Только пример, хоть и не правильный.</p>]]></content>
			<author>
				<name><![CDATA[MandarinKa02]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=34409</uri>
			</author>
			<updated>2019-02-24T21:37:02Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132488#p132488</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132487#p132487" />
			<content type="html"><![CDATA[<p>Ну, я бы сказал, что здесь семантически неправильно составлен список, в одну кучу свалены перечисления и заголовки групп объектов. Правильнее было бы так:<br /></p><div class="codebox"><pre><code>склад 1
	Список фруктов
		Яблоки,Груши,Ананас
	Настройки
		Размер
		Кол-во контейнеров
	Яблоки
		И тут разновидности
		в 100+ строк
	Груши
		и пошло, поехало
	Ананас
		к сожалению один, привоза не было

	Какой-нибудь объект, содержащий другую необходимую информацию о складе
		что-то внутри
	Размер
		500кв км.
	Кол-во контейнеров
		...
склад2 
	и.т.д</code></pre></div>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2019-02-24T21:11:11Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132487#p132487</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132486#p132486" />
			<content type="html"><![CDATA[<p>Опять же, была задача написать парсер, который бы выполнял свою работу без нареканий. А то, что в нашем случае &quot;Актюбинская область&quot; представляется в виде значения - это уже другой вопрос. Давайте приведу еще один пример.<br />Допустим, список фруктов на складах.<br /></p><div class="codebox"><pre><code>склад 1
	Яблоки,Груши,Ананас
	Настройки
		Размер
		Кол-во контейнеров
	Яблоки
		И тут разновидности
		в 100+ строк
	Груши
		и пошло, поехало
	Ананас
		к сожалению один, привоза не было

	Какой-нибудь объект, содержащий другую необходимую информацию о складе
		что-то внутри
	Размер
		500кв км.
	Кол-во контейнеров
		...
склад2 
	и.т.д
</code></pre></div><p>Что у нас здесь? А здесь у нас в объекте сами склады с порядковым номером. И в каждом из них в ячейке 1 будет находится список фруктов.<br />С вашим бы скриптом, вместо ячейки 1 был бы пустой объект с названием &quot;Яблоки,Груши,Ананас&quot;. И как бы я узнал, что здесь фрукт, а что не фрукт?</p>]]></content>
			<author>
				<name><![CDATA[MandarinKa02]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=34409</uri>
			</author>
			<updated>2019-02-24T20:56:05Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132486#p132486</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132485#p132485" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>MandarinKa02 пишет:</cite><blockquote><p>отредактировал код в посте 36.</p></blockquote></div><p>Теперь работает. В чём я тут вижу проблему:</p><p><span class="postimg"><img src="https://i.imgur.com/d9xlgoe.png" alt="https://i.imgur.com/d9xlgoe.png" /></span></p><p>&quot;Акмолинская область&quot; и &quot;Актюбинская область&quot; по идее родственные объекты, а представлены по-разному, да и порядок нарушен.<br /></p><div class="quotebox"><cite>MandarinKa02 пишет:</cite><blockquote><p>Не понял, что вы имеете ввиду?</p></blockquote></div><p>Ну, например было<br /></p><div class="codebox"><pre><code>МИР
	Казахстан
		Акмолинская область
			Акколь
			Степногорск
			Степняк
			Щучинск
		Актюбинская область
		Алматинская область
			Есик
			Жаркент
			Алматы
	РФ
		Ленинградская область
			Павловск
			Гатчина</code></pre></div><p>а потом в этот файл будут добавлены новые строки:<br /></p><div class="codebox"><pre><code>МИР
	Казахстан
		Акмолинская область
			Акколь
			Степногорск
			Степняк
			Щучинск
		Актюбинская область
			Актобе
			Хромтау
			Шалкар
			Эмба
		Алматинская область
			Есик
			Жаркент
			Алматы
	РФ
		Ленинградская область
			Павловск
			Гатчина</code></pre></div><p>Так вот в моём предыдущем варианте путь к &quot;Актюбинская область&quot; в старом и новом тексте будет одинаков, а в вашем нет.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2019-02-24T20:20:46Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132485#p132485</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132484#p132484" />
			<content type="html"><![CDATA[<p><strong>teadrinker</strong>, отредактировал код в посте 36.<br />Вам вариант ничем не плох, не подходит под мои нужды.<br /></p><div class="quotebox"><cite>teadrinker пишет:</cite><blockquote><p>возможного расширения исходного текста хорош</p></blockquote></div><p>Не понял, что вы имеете ввиду?</p>]]></content>
			<author>
				<name><![CDATA[MandarinKa02]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=34409</uri>
			</author>
			<updated>2019-02-24T20:02:14Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132484#p132484</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132482#p132482" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>MandarinKa02 пишет:</cite><blockquote><p>Да и возможно, это бы ухудшило производительность.</p></blockquote></div><p>А чем плох мой предыдущий вариант, где все строки — объекты? Он и в плане возможного расширения исходного текста хорош.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2019-02-24T19:53:29Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132482#p132482</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132481#p132481" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>MandarinKa02 пишет:</cite><blockquote><p>teadrinker, поправил.</p></blockquote></div><p>Не работает:<br /></p><div class="codebox"><pre><code>data =
(
МИР
	Казахстан
		Акмолинская область
			Акколь
			Степногорск
			Степняк
			Щучинск
		Актюбинская область
		Алматинская область
			Есик
			Жаркент
			Алматы
	РФ
		Ленинградская область
			Павловск
			Гатчина
)

obj := NEI.Parse(data)
MsgBox, % obj[&quot;МИР&quot;, &quot;Казахстан&quot;, &quot;Алматинская область&quot;, 3]

class NEI {
	Parse(input) {

		obj:=[]
		curObj:=obj,objStack:=[],objStack.Push(curObj)

		curTab:=prevLine:=prevTab:=-1
		Loop, Parse, input, `n, `r
		{
			if(!RegExMatch(A_LoopField, &quot;^(?&lt;tab&gt;`t*)(?&lt;line&gt;.*)&quot;, _) || !_line || RegExMatch(_line,&quot;^(\s{0,})\/\/&quot;)) ;empty line or &quot;//&quot; 
				Continue
			StrReplace(_tab, A_Tab, &quot;&quot;, tab)
			if(curTab=-1) {
				curTab:=0,prevLine:=_line
				if(prevTab:=tab) ;line starts with TAB and has&#039;t obj-parent
					return -1
				Continue
			} if(tab-curTab&lt;0) { ;prev level
				;msgbox % prevLine &quot;`n&quot; _line &quot;`n&quot; prevTab &quot;`n&quot; tab &quot;`n&quot; curTab
				;curObj.Push(prevLine)
				loop % Abs(tab-prevTab)
					objStack.Pop() ;remove last object
				;curTab:=prevTab
				curObj:=objStack[objStack.MaxIndex()]
			}

			if(tab=prevTab) ;curr level
				curObj.Push(prevLine)
			else if(tab&gt;prevTab) ;new level
				curObj[prevLine]:=[]
				,curObj:=curObj[prevLine]
				,objStack.Push(curObj)
				,curTab:=prevTab+1
			else if(prevTab-tab&gt;1)
				curObj[_line]:=[],curObj:=curObj[_line],objStack.Push(curObj)
			prevLine:=_line,prevTab:=tab
		} curObj.Push(prevLine)
		return obj
	}
	Dump(obj,tab=0) {
		if(!isObject(obj))
			return -1
		out:=&quot;&quot;
		for i,v in obj {
			if(isObject(v))
				out.=this._mult_tab(tab) i &quot;`n&quot; this.Dump(v,tab+1)
			out.=this._mult_tab(tab) v (A_Index=obj.MaxIndex()?&quot;&quot;:&quot;`n&quot;)
		} return out
	}
	_mult_tab(i) {
		out:=&quot;&quot;
		loop % i
			out.=A_Tab
		return out
	}
}</code></pre></div>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2019-02-24T19:51:02Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132481#p132481</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132480#p132480" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>teadrinker пишет:</cite><blockquote><p>Можно, но может путаница получиться. Придётся как-то отличать ключ со ссылкой от остальных ключей.</p></blockquote></div><p>Был вариант каждому объекту(т.е. экземпляру класса) задавать переменную parent(экземпляр класса родителя) и data(тот самый объект в котором содержаться спарсенные данные) и уже с этим как-то пробовать. Но не в этот раз. Да и возможно, это бы ухудшило производительность. <br /></p><div class="quotebox"><cite>teadrinker пишет:</cite><blockquote><p>alekserus258, идите в задницу.</p></blockquote></div><p>А что, так можно было? <img src="//forum.script-coding.com/img/smilies/lol.png" width="15" height="15" /></p>]]></content>
			<author>
				<name><![CDATA[MandarinKa02]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=34409</uri>
			</author>
			<updated>2019-02-24T19:50:39Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132480#p132480</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132474#p132474" />
			<content type="html"><![CDATA[<p><strong>teadrinker</strong>, поправил.<br /></p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header" data-lang-open="открыть спойлер" data-lang-close="скрыть спойлер"><strong>+</strong>&nbsp;открыть спойлер</div><div class="fancy_spoiler"><div class="codebox"><pre><code>
class NEI {
	Parse(input) {

		obj:=[]
		curObj:=obj,objStack:=[],objStack.Push(curObj)

		curTab:=prevLine:=prevTab:=-1
		Loop, Parse, input, `n, `r
		{
			if(!RegExMatch(A_LoopField, &quot;^(?&lt;tab&gt;`t*)(?&lt;line&gt;.*)&quot;, _) || !_line || RegExMatch(_line,&quot;^(\s{0,})\/\/&quot;)) ;empty line or &quot;//&quot; 
				Continue
			StrReplace(_tab, A_Tab, &quot;&quot;, tab)
			if(curTab=-1) {
				curTab:=0,prevLine:=_line
				if(prevTab:=tab) ;line starts with TAB and has&#039;t obj-parent
					return -1
				Continue
			} if(tab-curTab&lt;0) { ;prev level
				curObj.Push(prevLine)
				loop % Abs(tab-prevTab)
					objStack.Pop() ;remove last object
				curObj:=objStack[objStack.MaxIndex()]
			}

			if(tab=prevTab &amp;&amp; tab-curTab&gt;=0) ;curr level &amp;&amp; already added in line 20
				curObj.Push(prevLine)
			else if(tab&gt;prevTab) ;new level
				curObj[prevLine]:=[]
				,curObj:=curObj[prevLine]
				,objStack.Push(curObj)
				,curTab:=prevTab+1
			else if(prevTab-tab&gt;1)
				curObj[_line]:=[],curObj:=curObj[_line],objStack.Push(curObj)
			prevLine:=_line,prevTab:=tab
		} curObj.Push(prevLine)
		return obj
	}
	Dump(obj,tab=0) {
		if(!isObject(obj))
			return -1
		out:=&quot;&quot;
		for i,v in obj {
			if(isObject(v))
				out.=this._mult_tab(tab) i &quot;`n&quot; this.Dump(v,tab+1)
			out.=this._mult_tab(tab) v (A_Index=obj.MaxIndex()?&quot;&quot;:&quot;`n&quot;)
		} return out
	}
	_mult_tab(i) {
		out:=&quot;&quot;
		loop % i
			out.=A_Tab
		return out
	}
}
</code></pre></div></div></div><div class="quotebox"><cite>teadrinker пишет:</cite><blockquote><p>всё, у чего есть вложенные строки, должно быть ключами, а всё, у чего нет, значениями</p></blockquote></div><p>Именно.</p>]]></content>
			<author>
				<name><![CDATA[MandarinKa02]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=34409</uri>
			</author>
			<updated>2019-02-24T19:43:10Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132474#p132474</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Парсинг дерева]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=132473#p132473" />
			<content type="html"><![CDATA[<p>Можно, но может путаница получиться. Придётся как-то отличать ключ со ссылкой от остальных ключей.</p>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2019-02-24T19:42:43Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=132473#p132473</id>
		</entry>
</feed>
