Unity3D List compare

昨天處理到 server room 的 list update, 希望嘗試 list compare delegates, 結果把整個編程思路重新優化.

原本是希望找出 2 條 list 中的的不同的地方並且進行不同的操作.

List<RoomInfo> _newRooms = _serverRooms.FindAll(delegate(RoomInfo thisRoom) {
	return !mRooms.Exists(delegate(RoomInfo i){
				return i.name!=thisRoom.name;
			});
});

List<RoomInfo> _existButUpdatedRooms = _serverRooms.FindAll(delegate(RoomInfo thisRoom) {
	if( mRooms.Exists(delegate(RoomInfo i){return i.name!=thisRoom.name;}) )
	{
		return false; // exists but same.
	}
	RoomInfo _found = mRooms.Find(delegate(RoomInfo obj) {
		return thisRoom.name.Equals(obj.name);
	});
	if( ReferenceEquals(null,_found) )
	{
		return false; // not exists
	}
	if( thisRoom.playerCount!=_found.playerCount )
	{
		return true; // need update.
	}
	// little difference, but we don't care.
	return false;
});

// find non-existed room, remove those in mRooms
mRooms.RemoveAll(delegate(RoomInfo thisRoom) {
	return _serverRooms.Exists(delegate(RoomInfo i){
				return i.name!=thisRoom.name;
			} );
});

 

這是第一次寫的垃圾 code 也不知道是否能跑 XD, 一堆 delegate, 看也看傻了.

覺得太煩瑣就找一下是否有 short form. 然後就修改為

List<RoomInfo> _newRooms = _serverRooms.FindAll(thisRoom =>
	!mRooms.Exists(i=> i.name!=thisRoom.name)
);

List<RoomInfo> _existButUpdatedRooms = _serverRooms.FindAll(thisRoom=>{
	if( mRooms.Exists(i => i.name!=thisRoom.name) )
	{
		return false; // exists but same.
	}
	RoomInfo _found = mRooms.Find(obj => thisRoom.name.Equals(obj.name));
	if( ReferenceEquals(null,_found) )
	{
		return false; // not exists
	}
	if( thisRoom.playerCount!=_found.playerCount )
	{
		return true; // need update.
	}
	// little difference, but we don't care.
	return false;
});

// find non-existed room, remove those in mRooms
mRooms.RemoveAll(thisRoom => _serverRooms.Exists(i=>i.name!=thisRoom.name));

開始找到感覺, 然後又發現一些因為寫太長太曲折所以想錯的地方… double anti… 之類的地方.

也把常用的 room name checking 另寫 function.

_serverRooms.ForEach(_room => {
	RoomInfo _found = mOldRooms.Find(pt=>IsSameRoom(pt,_room) );
	if( _found!=null )
	{
		// update player numbers.
	}
	else
	{
		// if it's a new room
	}
});

// find non-existed room, remove those in mRooms
mOldRooms.RemoveAll(_room => !_serverRooms.Exists(pt=> IsSameRoom(pt,_room)) );

///////////////////////////////////////////////////
private bool IsSameRoom(RoomInfo _r1, RoomInfo _r2)
{
	return _r1.name.Equals(_r2.name);
}

 

又一次証明把coding 寫得精簡真的很重要. (O.o)>
Huan-Lin 文章中有列出4種的變種寫法.

Predicate<Employee> p1 = delegate(Employee e)    { return e.Name.StartsWith("J"); };
Predicate<Employee> p2 =                  (e) => { return e.Name.StartsWith("J"); };
Predicate<Employee> p3 =                   e  => { return e.Name.StartsWith("J"); };
Predicate<Employee> p4 =                   e  =>          e.Name.StartsWith("J")   ;

參考文件 : delegate

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

*

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料