第一次接觸Linq是在使用C#的時候,這種語法,在處理列表數據非常方便。如果想了解Linq的更多內容可以百度一下Linq,不過你不了解也沒關系,讓我在Lua中給你展示一下Linq的魅力。簡單點說,Linq就是讓忽略掉循環的部分,讓你更加專業相關的業務實現。算是一種語法糖。
簡單舉幾個例子
1、輸出一個類中的所有內容
local test1 = { Attribute1 = "Attribute1", Attribute2 = "Attribute2", Attribute3 = "Attribute3", } print(string.format("{%s}", table.concat(Linq:Linq(GetAttributes(test1)):Select(function(n) return string.format("%s:%s", n.k, n.v) end), ", ")))
輸出:
{Attribute2:Attribute2, Attribute1:Attribute1, Attribute3:Attribute3}
2、提取列表數據中的Id組裝成一個新的Id列表
local test2 = { { id = 1, name = "test2_1", value = "test2_1", }, { id = 2, name = "test2_2", value = "test2_2", }, { id = 3, name = "test2_3", value = "test2_3", }, { id = 4, name = "test2_4", value = "test2_4", }, { id = 5, name = "test2_5", value = "test2_5", }, { id = 6, name = "test2_6", value = "test2_6", }, } print(table.concat(Linq:Linq(test2):Select(function(n) return n.id end), ", "))
輸出:
1, 2, 3, 4, 5, 6
3、提取列表中id為單數的內容,組裝成一個新的列表
local temp = Linq:Linq(test2):Where(function(n) return n.id % 2 == 1 end) for i, item in ipairs(temp) do print(string.format("{%s}", table.concat(Linq:Linq(GetAttributes(item)):Select(function(n) return string.format("%s:%s", n.k, n.v) end), ", "))) end
輸出:
{id:1, name:test2_1, value:test2_1}
{id:3, name:test2_3, value:test2_3} {id:5, name:test2_5, value:test2_5}
4、從字典中組裝一個table出來,如果所有的Key都存在則返回數據,否則則返回nil
local test3 = { key1 = "key1", key2 = "key2", key3 = "key3", key4 = "key4", } local keys1 = {"key1", "key2", "key3"} local keys2 = {"key1", "key2", "key5"} local temp1 = {} local all = Linq:Linq(keys1):All(function(n) local item = test3[n] if item then temp1[n] = item end return item ~= nil end) if all then print(string.format("key1 {%s}", table.concat(Linq:Linq(GetAttributes(temp1)):Select(function(n) return string.format("%s:%s", n.k, n.v) end), ", "))) else print("key1 Error") end local all = Linq:Linq(keys2):All(function(n) local item = test3[n] if item then temp1[n] = item end return item ~= nil end) if all then print(string.format("key2 {%s}", table.concat(Linq:Linq(GetAttributes(temp1)):Select(function(n) return string.format("%s:%s", n.k, n.v) end), ", "))) else print("key2 Error") end
輸出:
key1 {key1:key1, key3:key3, key2:key2}
key2 Error
綜述
Linq的用處還有很多,需要你發揮想象力來使用它,這個地方我就不做過多的贅述了。下面我來簡單的說明一下能夠使用的方法。
能用的函數
Linq:Linq
傳入一個列表類型的table,以后的操作都以列表類型為基礎進行操作。方法內容會將傳過來的對象Clone一份,不會破壞原來的數據。So放心大膽的用,雖然,Linq支持將列表類傳遞進來使用,但是我依然不推薦你這么用。
Select
這個函數會創建一個新的添加了Linq代碼的列表。你在調用這個函數的時候需要傳入一個函數,Linq會將列表中的每一項數據作為參數傳入該函,這個函數的返回值會插入到新的列表中返回。簡單點說。這個函數就是將原來的列表對象轉換為新的列表對象的方法。
Where
篩選函數。調用該函數時,需要傳入一個函數,Linq會吧列表中的數據,依次傳入該函數,並將該函數的返回值作為bool值判定,是否將這一對象添加到新列表中並返回。
Sum
求和函數,調用該函數時,需要闖入一個函數,Linq會把了你報中的數據,依次傳入該函數,並且將該函數的返回值累加起來返回。
All
判定函數,判定列表對象中所有的對象,是否都通過了校驗。調用這個函數的時候,需要傳入一個校驗函數,Linq會將列表中的每一項傳入校驗函數,並且接受校驗結果,如果任何一項判定失敗,則直接返回失敗,否則則返回成功。
Any
判定函數,判定列表對象中任何一個對象是否通過了校驗。調用這個函數的時候,需要傳入一個校驗函數,Linq會將列表中的每一項以此傳入校驗函數,如果任何一項的校驗結果判定成功,則直接返回成功,否則則返回失敗。
First
獲取函數,獲取數據的第一項。調用這個函數時,可以傳入一個校驗函數,如果存在校驗函數則以校驗成功的第一項作為結果返回。
Get
獲取函數,獲取某一個具體對象的數據。此函數的針對對象不是列表,而是某一個校驗對象。獲取校驗對象的名稱屬性。
Sort
排序函數,傳入一個排序函數,這個函數接受兩個值。該函數會將排好序的數據返回。
Clear
清理函數,清理數據中的Linq方法
疑問
1、使用Linq會不會破壞原來的數據?
不會,因為所有的數據都是從新Clone了一次,是操作Clone之后的數據,所以不會對原來的數據造成影響
2、使用Linq會不會降低性能?
會,但是影響應該不大。影響性能的主要因素主要有這么幾個:1、Clone,確實會影響一些,不過為了數據安全,這樣做還是很有必要的,再說使用Linq的時候一般是用來處理數據初始化,所以性能低一些也沒什么關系;2、列表的循環,我想這個應該不能算作是主要原因,因為你要做列表處理,肯定要使用循環,都有循環,所以這個沒什么關系;
最后
Linq只是一種處理列表數據的思想,使用這種數據處理列表會變得相對簡單,只關心直接相關的業務邏輯即可。書寫起來也比較方便。總之我比較喜歡這種方式。
相關的測試項目地址:http://git.oschina.net/anxin1225/LuaLinq