日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

自己动手,实现一种类似ListT的数据结构(二)

發(fā)布時(shí)間:2023/12/18 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自己动手,实现一种类似ListT的数据结构(二) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言:

首先,小匹夫要祝各位看官圣誕快樂(lè),新年愉快~。上一篇文章《自己動(dòng)手,實(shí)現(xiàn)一種類(lèi)似List<T>的數(shù)據(jù)結(jié)構(gòu)(一)》 介紹了一下不依靠List<T>實(shí)現(xiàn)的各種接口,仿造一個(gè)輕量級(jí)數(shù)據(jù)結(jié)構(gòu)的過(guò)程。可能有的看官會(huì)有一些疑問(wèn),例如一些功能可以通過(guò)Linq提供的拓展來(lái)實(shí)現(xiàn)呀。此言不虛但也不全對(duì),為了我們?cè)诠ぷ髦心芊奖愕牟僮骷隙峁┑倪@些拓展方法(包括我們自己也可以構(gòu)建的拓展方法),例如 Where,Any,Max,All...balalbala等等這些方法都是針對(duì)IEnumerable的對(duì)象進(jìn)行擴(kuò)展的,也就是說(shuō)需要實(shí)現(xiàn) IEnumerable接口。但是前面已經(jīng)說(shuō)了,小匹夫的用意是不實(shí)現(xiàn)各種List<T>繼承的接口。另外小匹夫的初衷是仿造和拓展 List<T>,將工作中需要使用到的各種功能集成到一個(gè)類(lèi)中,所以有些現(xiàn)成的拓展方法不需要,有一些沒(méi)有的方法小匹夫也會(huì)自己實(shí)現(xiàn)一下(當(dāng)然不是通過(guò)給現(xiàn)成的類(lèi)添加拓展方法這種方式)。當(dāng)然這篇文章介紹的東西還不成熟,需要慢慢完善,小匹夫也是把這個(gè)當(dāng)做一個(gè)學(xué)習(xí)和實(shí)踐的機(jī)會(huì)。好啦,解釋完畢,那就介紹下今天的內(nèi)容吧:

  • 實(shí)現(xiàn)的方法的名稱(chēng)和說(shuō)明列表
  • 增加了3個(gè)委托來(lái)抽象3種情況。
  • Map:通過(guò)委托把EggArray<T>中的每個(gè)值映射到一個(gè)新的EggArray<T>中
  • Difference:返回的值來(lái)自EggArray<T>中,但同時(shí)不是傳入的Other里面的值
  • Invoke:在EggArray<T>的每個(gè)元素上執(zhí)行methodName方法。
  • Pluck:萃取EggArray<T>中某字段值,返回一個(gè)數(shù)組,由于字段類(lèi)型不確定,所以需要裝箱。
  • Shuffle:返回一個(gè)隨機(jī)亂序的T[]副本。
  • 那么下面我們就書(shū)接上文,繼續(xù)我們仿照和拓展List<T>的步伐。

    Underscore.js的前緣

    咦,這不是一篇關(guān)于Csharp的文章嗎?怎么把JS給干出來(lái)?哈哈,當(dāng)然技術(shù)上并沒(méi)有什么必然的關(guān)系,只不過(guò)是小匹夫之前使用過(guò)cocos2d這套游戲引擎開(kāi)發(fā)過(guò)游戲,有一段時(shí)間也很癡迷于cocos2d-js這種使用JS就能開(kāi)發(fā)原生游戲的能力。所以也接觸了一些js庫(kù),對(duì)Underscore.js更是情有獨(dú)鐘。所以一提到要模仿List<T>這種內(nèi)部其實(shí)是Array的數(shù)據(jù)結(jié)構(gòu),一個(gè)靈感就是為何不嘗試實(shí)現(xiàn)一些Underscore.js數(shù)組部分的若干功能呢?所以下表EggArray<T>的新增方法中有部分借鑒于Underscore.js。

    新增方法表

    新增方法說(shuō)明
    First?返回EggArray<T> 的第一個(gè)元素。傳遞 n參數(shù)將返回?cái)?shù)組中從第一個(gè)元素開(kāi)始的n個(gè)元素
    Last?返回EggArray<T> 的最后一個(gè)元素。傳遞 n參數(shù)將返回?cái)?shù)組中從最后一個(gè)元素開(kāi)始的n個(gè)元素
    Slice?切割
    Get?預(yù)留
    Set?預(yù)留
    AddFirst?將對(duì)象添加到 EggArray<T> 的起始處。
    RemoveLast?EggArray<T> 中移除特定對(duì)象的最后一個(gè)匹配項(xiàng)。
    ContainsStrict?確定某元素是否在 EggArray<T> 中。(嚴(yán)格判斷是否是同一個(gè)對(duì)象)
    IndexOfStrict?搜索指定的對(duì)象,并返回整個(gè) EggArray<T> 中第一個(gè)匹配項(xiàng)的從零開(kāi)始的索引。(同上)
    TryGet?獲取指定類(lèi)型對(duì)象
    LastIndexOf?搜索指定的對(duì)象,并返回整個(gè) EggArray<T> 中第一個(gè)匹配項(xiàng)的從結(jié)尾開(kāi)始的索引。
    Map?通過(guò)委托把EggArray<T>中的每個(gè)值映射到一個(gè)新的EggArray<T>
    Filter?遍歷EggArray<T>中的每個(gè)值,返回包含所有通過(guò)predicate真值檢測(cè)的元素值。
    Without?返回一個(gè)刪除所有values值后的 EggArray<T>副本。
    FindEggArray<T>中逐項(xiàng)查找,返回第一個(gè)通過(guò)predicate迭代函數(shù)真值檢測(cè)的元素值
    Every如果EggArray<T>中的所有元素都通過(guò)predicate的真值檢測(cè)就返回true。
    Some如果EggArray<T>中有任何一個(gè)元素通過(guò) predicate 的真值檢測(cè)就返回true。
    Partition拆分一個(gè)EggArray<T>為兩個(gè)數(shù)組: ?第一個(gè)數(shù)組其元素都滿足predicate迭代函數(shù), 而第二個(gè)的所有元素均不能滿足predicate迭代函數(shù)
    Difference返回的值來(lái)自EggArray<T>中,但同時(shí)不是傳入的Other里面的值
    Uniq返回 EggArray<T>去重后的副本
    InvokeEggArray<T>的每個(gè)元素上執(zhí)行methodName方法。
    Pluck萃取EggArray<T>中元素某屬性值,返回一個(gè)數(shù)組。
    Shuffle返回一個(gè)隨機(jī)亂序的T[]副本
    SampleEggArray<T>中產(chǎn)生一個(gè)隨機(jī)樣本。傳遞一個(gè)數(shù)字表示從EggArray<T>中返回n個(gè)隨機(jī)元素。否則將返回一個(gè)單一的隨機(jī)項(xiàng)。

    ?

    各位看官可以看到,增加了許多挺有趣的功能。為了能將表中的功能名字變成真正的功能,我們還需要對(duì)上一篇文章中的變量&屬性部分做一些增改,如下我們?cè)黾恿?個(gè)委托來(lái)抽象3種情況。

    //定義三個(gè)委托來(lái)處理具體邏輯 public delegate void IterationHandler(T item); public delegate bool IterationBoolHandler(T item); public delegate T IterationVauleHandler(T item);

    同時(shí)為了能測(cè)試我們的功能,我們還要定義一個(gè)用來(lái)被當(dāng)做元素測(cè)試的類(lèi)。

    //被測(cè)試類(lèi) public class TargetClass {public int id;public string name;public TargetClass(int id){this.id = id;this.name = "NO. " + id;}public void Hi(){Debug.Log ("say hi");} }

    同時(shí)還要有一個(gè)測(cè)試的環(huán)境,因?yàn)樾∑シ蚴怯胢ac做unity3d的開(kāi)發(fā),所以就直接使用unity3d的環(huán)境了。

    /// <summary> /// Egg array test.Based on Unity3D,各個(gè)元素的id為0-9 /// </summary> using UnityEngine; using System.Collections; using EggToolkit; public class EggArrayTest : MonoBehaviour {EggArray<TargetClass> testArray = new EggArray<TargetClass>();// Use this for initializationvoid Start () {for(int i = 0; i < 10; i++){TargetClass test = new TargetClass(i);testArray.Add(test);} // Test_Difference(); // Test_Invoke(); // Test_Pluck(); // Test_Shuffle(); // Test_Map(); }void Update () {} }

    ?

    下面就讓小匹夫帶領(lǐng)大家分析幾個(gè)具體的函數(shù),并進(jìn)行下測(cè)試吧。

    Map:

    使用了IterationVauleHandler這個(gè)委托,即需要返回一個(gè)T類(lèi)型的值。

    //通過(guò)委托把EggArray<T>中的每個(gè)值映射到一個(gè)新的EggArray<T>中 public EggArray<T> Map(EggArray<T>.IterationVauleHandler handler) {EggArray<T> targetArray = new EggArray<T>(this.capacity);for(int i = 0; i < this.count; i++){T t = handler(this.items[i]);targetArray.Add(t);}return targetArray; }

    EggArrayTest中實(shí)現(xiàn)Test_Map這個(gè)方法:

    void Test_Map() {EggArray<TargetClass> newArray = testArray.Map(delegate(TargetClass item) {TargetClass newItem = new TargetClass(1);newItem.id = item.id * 10;return newItem;});newArray.Foreach(delegate(TargetClass item) {Debug.Log (item.id);}); }

    //原元素的id為0-9,輸出為0,10,20...90

    ?

    Difference:

    調(diào)用了Filter方法,其中Filter方法的參數(shù)是一個(gè)IterationBoolHandler委托,即一個(gè)返回bool值的委托。具體可以看Filter的實(shí)現(xiàn)。

    /// <summary> /// Difference the specified others. ///輸出不包含others中元素的EggArray<T> /// </summary> /// <param name="others">Others.</param> public EggArray<T> Difference(EggArray<T> others) {EggArray<T> targetArray = new EggArray<T>();targetArray = this.Filter(delegate(T item) {bool b = !others.Contains(item);return b;});return targetArray; }

    EggArrayTest中實(shí)現(xiàn)Test_Difference這個(gè)方法:

    ?

    //作為參數(shù)傳入的EggArray<T>由testArray的第5,第9這2個(gè)元素組成 void Test_Difference() {EggArray<TargetClass> differentArray = new EggArray<TargetClass>();differentArray.Add(testArray.Get(5));differentArray.Add(testArray.Get(9));testArray.Difference(differentArray).Foreach(delegate(TargetClass item) {Debug.Log(item.name);}); } //輸出缺少no. 5,no. 9這兩個(gè)name

    ?

    Invoke:

    EggArray<T>的每個(gè)元素上執(zhí)行methodName方法。

    /// <summary> /// Invoke the specified methodName. /// 每個(gè)元素上執(zhí)行methodName方法,若方法不存在則拋出exception /// </summary> /// <param name="methodName">Method name.</param> public void Invoke(string methodName) {Type t = typeof(T);var method = t.GetMethod(methodName);if(method == null)throw new Exception("沒(méi)有找到指定的方法哦~,可能不叫" + methodName);for(int i = 0; i < this.count; i++){method.Invoke(this.items[i], null);} }

    EggArrayTest中實(shí)現(xiàn)Test_Invoke這個(gè)方法:

    //調(diào)用TargetClass的HI()方法 void Test_Invoke() {testArray.Invoke("Hi"); }//輸出:say hi

    ?

    Pluck:

    萃取EggArray<T>中某字段值,返回一個(gè)數(shù)組,由于字段類(lèi)型不確定,所以需要裝箱。當(dāng)傳入的名稱(chēng)無(wú)法查找到該字段時(shí),拋出exception。

    /// <summary> /// Pluck the specified fieldName. /// 萃取某字段值,返回一個(gè)數(shù)組 /// 由于字段類(lèi)型不確定,所以需要裝箱 /// </summary> /// <param name="fieldName">Field name.</param> public object[] Pluck(string fieldName) {Type t = typeof(T);object[] targetArray = new object[this.count];var field = t.GetField(fieldName);if(field == null)throw new Exception("沒(méi)有找到指定的field哦~,可能不叫" + fieldName);for(int i = 0; i < this.count; i++){object value = field.GetValue(this.items[i]);targetArray[i] = value;}return targetArray; }

    EggArrayTest中實(shí)現(xiàn)Test_Pluck這個(gè)方法:

    ?

    //獲取各個(gè)元素 字段id的值 void Test_Pluck() {object[] testObj = testArray.Pluck("id");string testString = string.Empty;for(int i = 0; i < testObj.Length; i++){testString = testObj[i].ToString();Debug.Log ("field value is " + testString);} }//輸出為0-9

    ?

    ?

    Shuffle:

    返回一個(gè)隨機(jī)亂序的T[],下面看代碼

    /// <summary> /// Shuffle this instance. /// 返回一個(gè)隨機(jī)亂序的副本 /// </summary> public T[] Shuffle() {T[] shuffled = new T[this.count];Random random = new Random();for (int index = 0, rand; index < this.count; index++) {rand = random.Next(index);if (rand != index) shuffled[index] = shuffled[rand];shuffled[rand] = this.items[index];}return shuffled; }

    EggArrayTest中實(shí)現(xiàn)Test_Shuffle這個(gè)方法:

    ?

    // void Test_Shuffle() {TargetClass[] test = testArray.Shuffle();for(int i = 0; i < test.Length; i++){Debug.Log (test[i].name);} }//默認(rèn)順序?yàn)镹O. 0 ~ NO. 9 //亂序后,見(jiàn)圖

    ?

    好了,這周就到這里~小匹夫最近也在趕項(xiàng)目的途中,所以測(cè)試和修改的精力也被消耗了很多。過(guò)完元旦之后,再繼續(xù)~

    末了還是要說(shuō)一聲:各位元旦快樂(lè)~

    完整的代碼和測(cè)試可以在這里獲取:https://github.com/chenjd/Unity3D_EggArray

    裝模作樣的聲明一下:本博文章若非特殊注明皆為原創(chuàng),若需轉(zhuǎn)載請(qǐng)保留原文鏈接及作者信息慕容小匹夫

    轉(zhuǎn)載于:https://www.cnblogs.com/murongxiaopifu/p/4176620.html

    總結(jié)

    以上是生活随笔為你收集整理的自己动手,实现一种类似ListT的数据结构(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。