Показать сообщение отдельно
Старый 17.04.2012, 23:21
Psycho Tiger вне форума Посмотреть профиль Отправить личное сообщение для Psycho Tiger Найти все сообщения от Psycho Tiger
  № 5  
Ответить с цитированием
Psycho Tiger
 
Аватар для Psycho Tiger

блогер
Регистрация: Jun 2005
Адрес: Toronto
Сообщений: 6,601
Записей в блоге: 17
Разомнул мозги.
Метод может не создавать полные копии объектов в объектах, если в оригинале он null - просто пишет в результирующий объект ссылку.

Код AS3:
package {
	import artshlagin.utils.Tracer;
	import flash.display.Sprite;
	import flash.events.Event;
 
	/**
	 * ...
	 * @author Artem Shlagin
	 */
	public class Main extends Sprite {
 
		public function Main():void {
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void {
			removeEventListener(Event.ADDED_TO_STAGE, init);
			var objOriginal:Object = {
			   a: "a",
			   b: "1",
			   c: {
				  sub1: false,
				  sub2: {
					 x:10,
					 y:20,
					 z:null
				  }
			   }
			}
 
			var objChanged:Object = {
			   a: "a",
			   b: "2",
			   c: {
				  sub1: false,
				  sub2: {
					 x:10,
					 y:20,
					 z:{
						z_param: [1,2,3,4, "last"]
					 }
				  }
			   }
			}
			var objResult:Object = theSuperFunction(objOriginal, objChanged);
			Tracer.fullTraceObject(objResult);
 
		}
 
		private function theSuperFunction(objOriginal:Object, objChanged:Object):Object {
			var result:Object = { };
			if (!objOriginal) return objChanged;
			for (var name:String in objOriginal) {
				if (!(name in objChanged)) continue;
				if (isComposite(objOriginal[name])) {
					if (!isComposite(objChanged[name])) result[name] = objChanged[name];
					else{
						var temp:Object = theSuperFunction(objOriginal[name], objChanged[name]);
						if (!isEmpty(temp)) result[name] = temp;
					}
				}
				else {
					if (objChanged[name] !== objOriginal[name]) result[name] = objChanged[name];
				}
			}
			return result;
		}
 
		/**
		 * Что-то не пришло в голову лучшего способа проверки на хэш
		 * @param	object
		 * @return
		 */
		private function isComposite(object:*):Boolean {
			return typeof object === "object";
		}
		private function isEmpty(temp:Object):Boolean {
			for (var name:String in temp) {
				return false;
			}
			return true;
		}
 
 
 
	}
 
}
Код трейсера:
Код AS3:
package artshlagin.utils
{
	/**
	 * ...
	 * @author Artem Shlagin
	 */
	public class Tracer
	{
		public static var traceFunction:Function = trace;
		public static var nameDelimiter:String = " => ";
		public function Tracer()
		{
			throw new Error("Class is static");
		}
 
		public static function fullTraceObject(object:Object):void {
			recoursiveTrace(object);
		}
 
		private static function recoursiveTrace(o:Object, startValue:int = 0):void {
			for (var name:Object in o)
			{
				var otst:String = "";
				if (startValue > 0) {
					var i:int = startValue;
					while (i--) otst += "     ";
				}
				traceFunction.call(null, otst + name + nameDelimiter + o[name]);
				if ((typeof o[name]) === "object") recoursiveTrace(o[name], startValue+1);
			}
 
		}
 
	}
}
Результат:
Код:
b => 2
c => [object Object]
     sub2 => [object Object]
          z => [object Object]
               z_param => 1,2,3,4,last
                    0 => 1
                    1 => 2
                    2 => 3
                    3 => 4
                    4 => last
Но не ручаюсь за правильность работы во всех ситуациях.