<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; Клонируем объекты в Node.js]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=8736</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=8736&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «Клонируем объекты в Node.js».]]></description>
		<lastBuildDate>Mon, 07 Oct 2013 18:42:53 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: Клонируем объекты в Node.js]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=75834#p75834</link>
			<description><![CDATA[<div class="quotebox"><blockquote><p>Нет возможности сразу получить требуемую структуру из БД?</p></blockquote></div><p>Нет. Если в ближайшее время решение, по мотивам которого написан этот пост, не уйдет в продакшн - покажу - на мой взгляд &quot;уникальный&quot; движок на Node.js, весь такой &quot;сео&quot;, в общем сам тащусь <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />. <br />Ну если уйдет - найду время, напишу еще вкуснее и все равно покажу <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />, сейчас мне приятно думать что это кому-нибудь будет интересно. И будет понятно почему &quot;Нет возможности сразу получить требуемую структуру из БД&quot;. <br /></p><div class="quotebox"><blockquote><p>Это решается просто - эмуляцией:</p></blockquote></div><p>Согласен. В моем случае <a href="https://developers.google.com/v8/intro">V8</a> с&nbsp; <a href="http://www.ecma-international.org/ecma-262/5.1/">ECMA-262, 5th edition</a> дружит, поэтому можно без эмуляции, вы предложили&nbsp; &quot;браузерный&quot; вариант, хозяйкам на заметку <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />.<br />Хотелось как-то без обращения к прототипам, без велосипедов типа for (var prop in obj), ну вы поняли - заголовок поста - клонируем объект, хотя в моем случае нужно было создать объект с теми же свойствами - никаких методов, ссылок (тем более рекурсивных). <br />Короче если разработчик столкнется с подобной проблемой, прочитав этот пост наверняка сэкономит время.<br /></p><div class="quotebox"><blockquote><p>Object.create - это не клонирование объекта, а создание нового с указанием ему старого в качестве прототипа.</p></blockquote></div><p>Именно то, что в моем случае было нужно.<br /></p><div class="quotebox"><blockquote><p>Мне кажется, надо не клонировать объекты, а копировать только требуемые свойства.</p></blockquote></div><p>ДА, ДА, ДА ДА ДА <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />.<br /></p><div class="quotebox"><blockquote><p>Этот код в примере выполняется многократно для каждого найденного тега - по количеству категорий. Весьма накладная операция.</p></blockquote></div><p>В реальном приложении этот код выполняется раз в минуту - в процессе обновления и кэширования данных - на мой взгляд за это время можно справиться с любым объемом данных - хотя у меня пока только тестовые данные - хватает за глаза.</p>]]></description>
			<author><![CDATA[null@example.com (dab00)]]></author>
			<pubDate>Mon, 07 Oct 2013 18:42:53 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=75834#p75834</guid>
		</item>
		<item>
			<title><![CDATA[Re: Клонируем объекты в Node.js]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=75811#p75811</link>
			<description><![CDATA[<div class="quotebox"><blockquote><p>я ждал Ваш комментарий</p></blockquote></div><p>Я пришел и ничего не сказал. (-:</p><div class="quotebox"><blockquote><p>сущности из базы данных, имеющие отношение многие-ко-многим.</p></blockquote></div><p>Нет возможности сразу получить требуемую структуру из БД?</p><div class="quotebox"><blockquote><p>Object.create() из ECMAScript 5 на мой взгляд кошернее, но если использовать в браузере, то не уверен на счет оперы, старых ие и т.п.</p></blockquote></div><p>Это решается просто - эмуляцией:<br /></p><div class="codebox"><pre><code>
Object.create = Object.create || function(proto)
{
    var F = function() {};
    F.prototype = proto;
    return new F();
};
</code></pre></div><p>Полного соответствия стандарту в случае с Object.create Вы не добъетесь, но основную работу - создание нового объекта из заданного - функция делает. Но это совсем не клонирование.</p><p>Чтобы уж совсем сотрясанием воздуха не было мое сообщение. </p><p>Если Вам нужна функция клонирования - напишите свою - не используйте функции не по назначению. Object.create - это не клонирование объекта, а создание нового с указанием ему старого в качестве прототипа. </p><div class="quotebox"><blockquote><p>Становится понятно, что изменять свойства иходных объектов нам ни к чему, а нужно эти самые объекты как-то клонировать.</p></blockquote></div><p>Мне кажется, надо не клонировать объекты, а копировать только требуемые свойства. </p><div class="codebox"><pre><code>tag = JSON.parse(JSON.stringify(cache.tag[k]));</code></pre></div><p>Этот код в примере выполняется многократно для каждого найденного тега - по количеству категорий. Весьма накладная операция.</p>]]></description>
			<author><![CDATA[null@example.com (Rumata)]]></author>
			<pubDate>Sun, 06 Oct 2013 17:35:59 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=75811#p75811</guid>
		</item>
		<item>
			<title><![CDATA[Re: Клонируем объекты в Node.js]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=75806#p75806</link>
			<description><![CDATA[<p><strong>Rumata</strong>, я ждал Ваш комментарий <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />, может еще какие-нибудь варианты клонирования объектов в JavaScript (хорошие).<br />Мне &quot;двойная конвертация&quot; тоже не особенно понравилась, хотя в моем случае достаточно и этого. <br />Object.create() из ECMAScript 5 на мой взгляд кошернее, но если использовать в браузере, то не уверен на счет оперы, старых ие и т.п.<br /></p><div class="quotebox"><blockquote><p>Каким образом node-js улучшил именно саму процедуру получения струтктур я не понял.</p></blockquote></div><p>Не знаю на счет &quot;улучшил&quot;, но использованный мною стандартный модуль util устроен <a href="https://github.com/joyent/node/blob/master/lib/util.js">вот так</a>.<br />На счет данных - если посмотреть на них повнимательнее, можно сделать правильный вывод, что это сущности из базы данных, имеющие отношение многие-ко-многим.</p>]]></description>
			<author><![CDATA[null@example.com (dab00)]]></author>
			<pubDate>Sun, 06 Oct 2013 15:50:48 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=75806#p75806</guid>
		</item>
		<item>
			<title><![CDATA[Re: Клонируем объекты в Node.js]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=75803#p75803</link>
			<description><![CDATA[<div class="codebox"><pre><code>JSON.parse(JSON.stringify(obj))</code></pre></div><p>Я понимаю Ваши игру с двойной конвертацией, но предупреждаю - будьте осторожны: она не выполняет полного клорнирования и не работает с рекурсивными ссылками.</p><p>Если я правильно понял, Вам потребовалось из одной структуры данных получить другую. Каким образом node-js улучшил именно саму процедуру получения струтктур я не понял. Но Вы правильно заметили, что </p><div class="quotebox"><blockquote><p>Большинство изложенных примеров можно воспроизвести в консоли браузера</p></blockquote></div>]]></description>
			<author><![CDATA[null@example.com (Rumata)]]></author>
			<pubDate>Sun, 06 Oct 2013 14:26:13 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=75803#p75803</guid>
		</item>
		<item>
			<title><![CDATA[Клонируем объекты в Node.js]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=75794#p75794</link>
			<description><![CDATA[<p>Люблю я изобретать велосипеды. Не далее чем на прошлой неделе потратил немало времени на то, чтобы построить нужную структуру данных на <a href="http://nodejs.org/">Node.js</a>. Убедился, что найти информацию на подобный предмет в сети непросто, поэтому спешу сохранить кое-какой экспириенс. Большинство изложенных примеров можно воспроизвести в консоли браузера (Chrome, Firefox, за прочие не ручаюсь).</p><p>На входе есть данные, которые выглядят примерно так:<br /></p><div class="codebox"><pre><code>
var cache = {
  cat: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сладкий&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Горький&quot;}], 
  tag: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сахар&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Перец&quot;}], 
  tag_to_cat: [
    {&quot;tag_id&quot;:1, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:1, &quot;cat_id&quot;:2}, // &#039;Сладкий Сахар&#039;, &#039;Горький Сахар&#039;
    {&quot;tag_id&quot;:2, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:2, &quot;cat_id&quot;:2}, // &#039;Сладкий Перец&#039;, &#039;Горький Перец&#039;
  ]
}
</code></pre></div><p>На выходе нужно получить:<br /></p><div class="codebox"><pre><code>
cache.tag_by_cat:  [
  {&quot;id&quot;:1,&quot;name&quot;:&quot;Сладкий&quot;,&quot;path&quot;:&quot;Сладкий/&quot;,&quot;tag&quot;:[
    {&quot;id&quot;:1,&quot;name&quot;:&quot;Сахар&quot;,&quot;path&quot;:&quot;Сладкий/Сахар/&quot;},
    {&quot;id&quot;:2,&quot;name&quot;:&quot;Перец&quot;,&quot;path&quot;:&quot;Сладкий/Перец/&quot;}]},
  {&quot;id&quot;:2,&quot;name&quot;:&quot;Горький&quot;,&quot;path&quot;:&quot;Горький/&quot;,&quot;tag&quot;:[
    {&quot;id&quot;:1,&quot;name&quot;:&quot;Сахар&quot;,&quot;path&quot;:&quot;Горький/Сахар/&quot;},
    {&quot;id&quot;:2,&quot;name&quot;:&quot;Перец&quot;,&quot;path&quot;:&quot;Горький/Перец/&quot;}]}
]
</code></pre></div><p>Если начну рассказывать зачем - затяну песню на неделю... просто нужно <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />.</p><p>Открываем блокнот, я использую <a href="http://notepad-plus-plus.org/">Notepad++</a>, пишем код:<br /></p><div class="codebox"><pre><code>
var cache = {
  cat: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сладкий&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Горький&quot;}], 
  tag: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сахар&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Перец&quot;}], 
  tag_to_cat: [
    {&quot;tag_id&quot;:1, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:1, &quot;cat_id&quot;:2}, // &#039;Сладкий Сахар&#039;, &#039;Горький Сахар&#039;
    {&quot;tag_id&quot;:2, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:2, &quot;cat_id&quot;:2}, // &#039;Сладкий Перец&#039;, &#039;Горький Перец&#039;
  ]
}
cache.tag_by_cat = cache.cat.map(function(cat) {
  cat.path = cat.name + &#039;/&#039;;  
  cat.tag = cache.tag.filter(function(tag) {
    return cache.tag_to_cat.filter(function(tag_to_cat) {
      return tag_to_cat.cat_id == cat.id;
    }).map(function(tag_to_cat) {
      return tag_to_cat.tag_id
    }).indexOf(tag.id) !== -1;
  }).map(function(tag) {
    tag.path = cat.path + tag.name + &#039;/&#039;; 
    return tag;
  });
  return cat;
});
console.log(&#039;cache.tag_by_cat: &#039;, JSON.stringify(cache.tag_by_cat));
</code></pre></div><p>Выполняем:<br /><span class="postimg"><img src="http://4.bp.blogspot.com/-b4pyPkqiV5k/UlEPxZTD5rI/AAAAAAAAB5U/gFl6cO-r3m8/s1600/node-clone-1.jpg" alt="http://4.bp.blogspot.com/-b4pyPkqiV5k/UlEPxZTD5rI/AAAAAAAAB5U/gFl6cO-r3m8/s1600/node-clone-1.jpg" /></span></p><p>Получаем следующий объект:<br /></p><div class="codebox"><pre><code>
cache.tag_by_cat:  [
  {&quot;id&quot;:1,&quot;name&quot;:&quot;Сладкий&quot;,&quot;path&quot;:&quot;Сладкий/&quot;,&quot;tag&quot;:[
    {&quot;id&quot;:1,&quot;name&quot;:&quot;Сахар&quot;,&quot;path&quot;:&quot;Горький/Сахар/&quot;},
    {&quot;id&quot;:2,&quot;name&quot;:&quot;Перец&quot;,&quot;path&quot;:&quot;Горький/Перец/&quot;}]},
  {&quot;id&quot;:2,&quot;name&quot;:&quot;Горький&quot;,&quot;path&quot;:&quot;Горький/&quot;,&quot;tag&quot;:[
    {&quot;id&quot;:1,&quot;name&quot;:&quot;Сахар&quot;,&quot;path&quot;:&quot;Горький/Сахар/&quot;},
    {&quot;id&quot;:2,&quot;name&quot;:&quot;Перец&quot;,&quot;path&quot;:&quot;Горький/Перец/&quot;}]}
]
</code></pre></div><p>Тысяча чертей, сударь! Где мой Сладкий Сахар и Сладкий Перец?</p><p>Переписываем код &quot;по-стариковски&quot; - без мапов и фильтров - по-моему так будет&nbsp; понятнее что происходит:<br /></p><div class="codebox"><pre><code>
var cache = {
  cat: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сладкий&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Горький&quot;}], 
  tag: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сахар&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Перец&quot;}], 
  tag_to_cat: [
    {&quot;tag_id&quot;:1, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:1, &quot;cat_id&quot;:2}, // &#039;Сладкий Сахар&#039;, &#039;Горький Сахар&#039;
    {&quot;tag_id&quot;:2, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:2, &quot;cat_id&quot;:2}, // &#039;Сладкий Перец&#039;, &#039;Горький Перец&#039;
  ]
}
cache.tag_by_cat = [];
for (var i=0; i&lt;cache.cat.length; i++) {  
  cache.cat[i].path = cache.cat[i].name + &#039;/&#039;;
  cache.cat[i].tag = [];
  for (var j=0; j&lt;cache.tag_to_cat.length; j++) {
    if (cache.tag_to_cat[j].cat_id === cache.cat[i].id) {
      for (var k=0; k&lt;cache.tag.length; k++) {
        if (cache.tag[k].id === cache.tag_to_cat[j].tag_id) {          
          cache.tag[k].path = cache.cat[i].path + cache.tag[k].name + &#039;/&#039;;
          cache.cat[i].tag.push(cache.tag[k]);          
          break;
        }
      }
    }    
  }
  cache.tag_by_cat.push(cache.cat[i]);  
}
console.log(&#039;cache.tag_by_cat: &#039;, JSON.stringify(cache.tag_by_cat));
</code></pre></div><p>Выполняем:<br /><span class="postimg"><img src="http://4.bp.blogspot.com/-03NNT7B4Bd4/UlEQr8sl7CI/AAAAAAAAB5c/1A5Gfx_Afos/s1600/node-clone-2.jpg" alt="http://4.bp.blogspot.com/-03NNT7B4Bd4/UlEQr8sl7CI/AAAAAAAAB5c/1A5Gfx_Afos/s1600/node-clone-2.jpg" /></span></p><p>То же самое. Но теперь можно понять куда пропал Сладкий Сахар и Сладкий Перец.<br />Добавим в код пару строчек для вывода в консоль свойств исходных объектов cache.cat и cache.tag:<br /></p><div class="codebox"><pre><code>
console.log(&#039;cache.cat: &#039;, JSON.stringify(cache.cat));
console.log(&#039;cache.tag: &#039;, JSON.stringify(cache.tag));
</code></pre></div><p>Выполним код еще раз:<br /><span class="postimg"><img src="http://3.bp.blogspot.com/-lwp-ICdSBNc/UlERLPWhXfI/AAAAAAAAB5o/RQPXmNV2E2Y/s1600/node-clone-3.jpg" alt="http://3.bp.blogspot.com/-lwp-ICdSBNc/UlERLPWhXfI/AAAAAAAAB5o/RQPXmNV2E2Y/s1600/node-clone-3.jpg" /></span></p><p>Получаем следующие объекты:<br /></p><div class="codebox"><pre><code>
cache.cat:  [
  {&quot;id&quot;:1,&quot;name&quot;:&quot;Сладкий&quot;,&quot;path&quot;:&quot;Сладкий/&quot;,&quot;tag&quot;:[
    {&quot;id&quot;:1,&quot;name&quot;:&quot;Сахар&quot;,&quot;path&quot;:&quot;Горький/Сахар/&quot;},
    {&quot;id&quot;:2,&quot;name&quot;:&quot;Перец&quot;,&quot;path&quot;:&quot;Горький/Перец/&quot;}]},
  {&quot;id&quot;:2,&quot;name&quot;:&quot;Горький&quot;,&quot;path&quot;:&quot;Горький/&quot;,&quot;tag&quot;:[
    {&quot;id&quot;:1,&quot;name&quot;:&quot;Сахар&quot;,&quot;path&quot;:&quot;Горький/Сахар/&quot;},
    {&quot;id&quot;:2,&quot;name&quot;:&quot;Перец&quot;,&quot;path&quot;:&quot;Горький/Перец/&quot;}]}
]
cache.tag:  [
  {&quot;id&quot;:1,&quot;name&quot;:&quot;Сахар&quot;,&quot;path&quot;:&quot;Горький/Сахар/&quot;},
  {&quot;id&quot;:2,&quot;name&quot;:&quot;Перец&quot;,&quot;path&quot;:&quot;Горький/Перец/&quot;}
]
</code></pre></div><p>Становится понятно, что изменять свойства иходных объектов нам ни к чему, а нужно эти самые объекты как-то клонировать.<br />Первое, что приходит на ум - JSON.parse(JSON.stringify(obj)):<br /></p><div class="codebox"><pre><code>
var cache = {
  cat: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сладкий&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Горький&quot;}], 
  tag: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сахар&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Перец&quot;}], 
  tag_to_cat: [
    {&quot;tag_id&quot;:1, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:1, &quot;cat_id&quot;:2}, // &#039;Сладкий Сахар&#039;, &#039;Горький Сахар&#039;
    {&quot;tag_id&quot;:2, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:2, &quot;cat_id&quot;:2}, // &#039;Сладкий Перец&#039;, &#039;Горький Перец&#039;
  ]
}
cache.tag_by_cat = [];
var cat, tag;
for (var i=0; i&lt;cache.cat.length; i++) {
  cat = JSON.parse(JSON.stringify(cache.cat[i]));
  cat.path = cat.name + &#039;/&#039;;
  cat.tag = [];
  for (var j=0; j&lt;cache.tag_to_cat.length; j++) {
    if (cache.tag_to_cat[j].cat_id === cache.cat[i].id) {
      for (var k=0; k&lt;cache.tag.length; k++) {
        if (cache.tag[k].id === cache.tag_to_cat[j].tag_id) {
          tag = JSON.parse(JSON.stringify(cache.tag[k]));
          tag.path = cat.path + tag.name + &#039;/&#039;;
          cat.tag.push(tag);          
          break;
        }
      }
    }    
  }
  cache.tag_by_cat.push(cat);  
}
console.log(&#039;cache.tag_by_cat: &#039;, JSON.stringify(cache.tag_by_cat));
</code></pre></div><p>Выполняем:<br /><span class="postimg"><img src="http://1.bp.blogspot.com/-RDuBwY9mVtU/UlERxHJSslI/AAAAAAAAB5w/mK0VX_pviLw/s1600/node-clone-4.jpg" alt="http://1.bp.blogspot.com/-RDuBwY9mVtU/UlERxHJSslI/AAAAAAAAB5w/mK0VX_pviLw/s1600/node-clone-4.jpg" /></span></p><p>Bingo! То, что нужно:<br /></p><div class="codebox"><pre><code>
cache.tag_by_cat:  [
  {&quot;id&quot;:1,&quot;name&quot;:&quot;Сладкий&quot;,&quot;path&quot;:&quot;Сладкий/&quot;,&quot;tag&quot;:[
    {&quot;id&quot;:1,&quot;name&quot;:&quot;Сахар&quot;,&quot;path&quot;:&quot;Сладкий/Сахар/&quot;},
    {&quot;id&quot;:2,&quot;name&quot;:&quot;Перец&quot;,&quot;path&quot;:&quot;Сладкий/Перец/&quot;}]},
  {&quot;id&quot;:2,&quot;name&quot;:&quot;Горький&quot;,&quot;path&quot;:&quot;Горький/&quot;,&quot;tag&quot;:[
    {&quot;id&quot;:1,&quot;name&quot;:&quot;Сахар&quot;,&quot;path&quot;:&quot;Горький/Сахар/&quot;},
    {&quot;id&quot;:2,&quot;name&quot;:&quot;Перец&quot;,&quot;path&quot;:&quot;Горький/Перец/&quot;}]}
]
</code></pre></div><p>Но, согласитесь, как-то не по фэн-шую.<br />Еще один вариант - <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.3.5">Object.create()</a>:<br /></p><div class="codebox"><pre><code>
var cache = {
  cat: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сладкий&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Горький&quot;}], 
  tag: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сахар&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Перец&quot;}], 
  tag_to_cat: [
    {&quot;tag_id&quot;:1, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:1, &quot;cat_id&quot;:2}, // &#039;Сладкий Сахар&#039;, &#039;Горький Сахар&#039;
    {&quot;tag_id&quot;:2, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:2, &quot;cat_id&quot;:2}, // &#039;Сладкий Перец&#039;, &#039;Горький Перец&#039;
  ]
}
cache.tag_by_cat = [];
var cat, tag;
for (var i=0; i&lt;cache.cat.length; i++) {
  cat = Object.create(cache.cat[i]);
  cat.path = cat.name + &#039;/&#039;;
  cat.tag = [];
  for (var j=0; j&lt;cache.tag_to_cat.length; j++) {
    if (cache.tag_to_cat[j].cat_id === cache.cat[i].id) {
      for (var k=0; k&lt;cache.tag.length; k++) {
        if (cache.tag[k].id === cache.tag_to_cat[j].tag_id) {
          tag = Object.create(cache.tag[k]);
          tag.path = cat.path + tag.name + &#039;/&#039;;
          cat.tag.push(tag);          
          break;
        }
      }
    }    
  }
  cache.tag_by_cat.push(cat);  
}
console.log(&#039;cache.tag_by_cat: &#039;, JSON.stringify(cache.tag_by_cat));
</code></pre></div><p>Выполняем:<br /><span class="postimg"><img src="http://3.bp.blogspot.com/-96tU0lmtSc8/UlESZaZ57RI/AAAAAAAAB54/a72_v4tzGIE/s1600/node-clone-5.jpg" alt="http://3.bp.blogspot.com/-96tU0lmtSc8/UlESZaZ57RI/AAAAAAAAB54/a72_v4tzGIE/s1600/node-clone-5.jpg" /></span></p><p>Все ОК. На первый взгляд не совсем - не видим свойства объекта, унаследованные от прототипа, но они есть, просто &quot;<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create?redirectlocale=en-US&amp;redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FObject%2Fcreate">by default properties ARE NOT writable, enumerable or configurable</a>&quot;.<br />Для того, чтобы убедиться в их существовании добавим в код несколько строчек:<br /></p><div class="codebox"><pre><code>
cache.tag_by_cat.forEach(function(cat) {
  console.log(&#039;cat.id: &#039; + cat.id + &#039;\n&#039; + &#039;cat.name: &#039; + cat.name + &#039;\n&#039; + &#039;cat.tag: &#039; + JSON.stringify(cat.tag));
  cat.tag.forEach(function(tag) {
    console.log(&#039;tag.id: &#039; + tag.id + &#039;\n&#039; + &#039;tag.name: &#039; + tag.name + &#039;\n&#039; + &#039;tag.path: &#039; + tag.path);
  });
});
</code></pre></div><p>Выполняем:<br /><span class="postimg"><img src="http://4.bp.blogspot.com/-BBQgdgprK4c/UlETB-91KiI/AAAAAAAAB6M/cUh1H9IDoE4/s1600/node-clone-6.jpg" alt="http://4.bp.blogspot.com/-BBQgdgprK4c/UlETB-91KiI/AAAAAAAAB6M/cUh1H9IDoE4/s1600/node-clone-6.jpg" /></span></p><p>Теперь точно все ОК.<br />Еще один, &quot;нативный&quot; для Node.js, вариант с использованием require(&#039;util&#039;)._extend:<br /></p><div class="codebox"><pre><code>
var extend = require(&#039;util&#039;)._extend;
var cache = {
  cat: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сладкий&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Горький&quot;}], 
  tag: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сахар&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Перец&quot;}], 
  tag_to_cat: [
    {&quot;tag_id&quot;:1, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:1, &quot;cat_id&quot;:2}, // &#039;Сладкий Сахар&#039;, &#039;Горький Сахар&#039;
    {&quot;tag_id&quot;:2, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:2, &quot;cat_id&quot;:2}, // &#039;Сладкий Перец&#039;, &#039;Горький Перец&#039;
  ]
}
cache.tag_by_cat = [];
var cat, tag;
for (var i=0; i&lt;cache.cat.length; i++) {
  cat = extend({path: cache.cat[i].name + &#039;/&#039;}, cache.cat[i])
  cat.tag = [];
  for (var j=0; j&lt;cache.tag_to_cat.length; j++) {
    if (cache.tag_to_cat[j].cat_id === cache.cat[i].id) {
      for (var k=0; k&lt;cache.tag.length; k++) {
        if (cache.tag[k].id === cache.tag_to_cat[j].tag_id) {
          tag = extend({path: cat.path + cache.tag[k].name + &#039;/&#039;}, cache.tag[k])
          cat.tag.push(tag);          
          break;
        }
      }
    }    
  }
  cache.tag_by_cat.push(cat);  
}
console.log(&#039;cache.tag_by_cat: &#039;, JSON.stringify(cache.tag_by_cat));
</code></pre></div><p>Выполняем:<br /><span class="postimg"><img src="http://2.bp.blogspot.com/-PFAIZuguj4o/UlETlWi8QeI/AAAAAAAAB6U/poGoPGNZ_P8/s1600/node-clone-7.jpg" alt="http://2.bp.blogspot.com/-PFAIZuguj4o/UlETlWi8QeI/AAAAAAAAB6U/poGoPGNZ_P8/s1600/node-clone-7.jpg" /></span></p><p>Окончательный вариант кода может выглядеть следующим образом:<br /></p><div class="codebox"><pre><code>
var extend = require(&#039;util&#039;)._extend;
var cache = {
  cat: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сладкий&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Горький&quot;}], 
  tag: [{&quot;id&quot;:1, &quot;name&quot;:&quot;Сахар&quot;}, {&quot;id&quot;:2, &quot;name&quot;:&quot;Перец&quot;}], 
  tag_to_cat: [
    {&quot;tag_id&quot;:1, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:1, &quot;cat_id&quot;:2}, // &#039;Сладкий Сахар&#039;, &#039;Горький Сахар&#039;
    {&quot;tag_id&quot;:2, &quot;cat_id&quot;:1}, {&quot;tag_id&quot;:2, &quot;cat_id&quot;:2}, // &#039;Сладкий Перец&#039;, &#039;Горький Перец&#039;
  ]
}
cache.tag_by_cat = cache.cat.map(function(cat) {  
  cat = extend({path: cat.name + &#039;/&#039;}, cat)
  cat.tag = cache.tag.filter(function(tag) {
    return cache.tag_to_cat.filter(function(tag_to_cat) {
      return tag_to_cat.cat_id == cat.id;
    }).map(function(tag_to_cat) {
      return tag_to_cat.tag_id
    }).indexOf(tag.id) !== -1;
  }).map(function(tag) {
    return extend({path: cat.path + tag.name + &#039;/&#039;}, tag);
  });  
  return cat;
});
console.log(&#039;cache.tag_by_cat: &#039;, JSON.stringify(cache.tag_by_cat));
</code></pre></div><p>Вот как-то так. Есть вариант лучше?</p>]]></description>
			<author><![CDATA[null@example.com (dab00)]]></author>
			<pubDate>Sun, 06 Oct 2013 12:13:45 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=75794#p75794</guid>
		</item>
	</channel>
</rss>
