讓Lua支持Linq吧


第一次接觸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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM