• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

游戏开发

常州微信小程序开发:实现一种类似List<T>的数据

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/youxikaifa/2018/1223/261.html

常州微信小程序开发:实现一种类似List<T>的数据结构(一)

前言:

  首先,常州微信小程序专业开发-幻天网络要祝各位看官圣诞快乐,新年愉快~。上一篇文章《自己动手,实现一种类似List的数据结构(一)》 介绍了一下不依靠List实现的各种接口,仿造一个轻量级数据结构的过程。可能有的看官会有一些疑问,例如一些功能可以通过Linq提供的拓展来实现呀。此言不虚但也不全对,为了我们在工作中能方便的操作集合而提供的这些拓展方法(包括我们自己也可以构建的拓展方法),例如 Where,Any,Max,All...balalbala等等这些方法都是针对IEnumerable的对象进行扩展的,也就是说需要实现 IEnumerable接口。但是前面已经说了,常州网站开发建设的用意是不实现各种List继承的接口。另外幻天的初衷是仿造和拓展 List,将工作中需要使用到的各种功能集成到一个类中,所以有些现成的拓展方法不需要,有一些没有的方法幻天网络也会自己实现一下(当然不是通过给现成的类添加拓展方法这种方式)。当然这篇文章介绍的东西还不成熟,需要慢慢完善,游戏开发运营-幻天网络也是把这个当做一个学习和实践的机会。好啦,解释完毕,那就介绍下今天的内容吧。

1. 实现的方法的名称和说明列表

2. 增加了3个委托来抽象3种情况。

3. Map:通过委托把EggArray中的每个值映射到一个新的EggArray中。

4. Difference:返回的值来自EggArray中,但同时不是传入的Other里面的值

5. Invoke:在EggArray的每个元素上执行methodName方法。

6. Pluck:萃取EggArray中某字段值,返回一个数组,由于字段类型不确定,所以常州手游开发需要装箱。

 

7. Shuffle:返回一个随机乱序的T[]副本。

那么下面我们就书接上文,继续我们仿照和拓展List的步伐。

Underscore.js的前缘

咦,这不是一篇关于Csharp的文章吗?怎么把JS给干出来?哈哈,当然技术上并没有什么必然的关系,只不过是幻天之前使用过cocos2d这套游戏引擎开发过游戏,有一段时间也很痴迷于cocos2d-js这种使用JS就能开发原生游戏的能力。所以也接触了一些js库,对Underscore.js更是情有独钟。所以一提到要模仿List这种内部其实是Array的数据结构,一个灵感就是为何不尝试实现一些Underscore.js数组部分的若干功能呢?所以下表EggArray的新增方法中有部分借鉴于Underscore.js。

新增方法表

新增方法

说明

First

 返回EggArray 的第一个元素。传递 n参数将返回数组中从第一个元素开始的n个元素

Last

 返回EggArray 的最后一个元素。传递 n参数将返回数组中从最后一个元素开始的n个元素

Slice

 切割

Get

 预留

Set

 预留

AddFirst

 将对象添加到 EggArray 的起始处。

RemoveLast

 从 EggArray 中移除特定对象的最后一个匹配项。

ContainsStrict

 确定某元素是否在 EggArray 中。(严格判断是否是同一个对象)

IndexOfStrict

 搜索指定的对象,并返回整个 EggArray 中第一个匹配项的从零开始的索引。(同上)

TryGet

 获取指定类型对象

LastIndexOf

 搜索指定的对象,并返回整个 EggArray 中第一个匹配项的从结尾开始的索引。

Map

 通过委托把EggArray中的每个值映射到一个新的EggArray中

Filter

 遍历EggArray中的每个值,返回包含所有通过predicate真值检测的元素值。

Without

 返回一个删除所有values值后的 EggArray副本。

Find

在EggArray中逐项查找,返回第一个通过predicate迭代函数真值检测的元素值

Every

如果EggArray中的所有元素都通过predicate的真值检测就返回true。

Some

如果EggArray中有任何一个元素通过 predicate 的真值检测就返回true。

Partition

拆分一个EggArray为两个数组:  常州游戏开发培训第一个数组其元素都满足predicate迭代函数, 而第二个的所有元素均不能满足predicate迭代函数

Difference

返回的值来自EggArray中,但同时不是传入的Other里面的值

Uniq

返回 EggArray去重后的副本

Invoke

在EggArray的每个元素上执行methodName方法。

Pluck

萃取EggArray中元素某属性值,返回一个数组。

Shuffle

返回一个随机乱序的T[]副本

Sample

从 EggArray中产生一个随机样本。传递一个数字表示从EggArray中返回n个随机元素。否则将返回一个单一的随机项。

 

各位看官可以看到,增加了许多挺有趣的功能。为了能将表中的功能名字变成真正的功能,我们还需要对上一篇文章中的变量&属性部分做一些增改,如下我们增加了3个委托来抽象3种情况。

//定义三个委托来处理具体逻辑

public delegate void IterationHandler(T item);

public delegate bool IterationBoolHandler(T item);

public delegate T IterationVauleHandler(T item);

同时为了能测试我们的功能,我们还要定义一个用来被当做元素测试的类。

//被测试类

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");

    }

}

同时还要有一个测试的环境,因为常州软件技术培训是用mac做unity3d的开发,所以就直接使用unity3d的环境了。

///

/// Egg array test.Based on Unity3D,各个元素的id为0-9

///

using UnityEngine;

using System.Collections;

using EggToolkit;

public class EggArrayTest : MonoBehaviour {

    EggArray testArray = new EggArray();

    // Use this for initialization

    void 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 () {

    

    }

 

}

下面就让手机App外包-幻天网络带领大家分析几个具体的函数,并进行下测试吧。

Map:

使用了IterationVauleHandler这个委托,即需要返回一个T类型的值

//通过委托把EggArray中的每个值映射到一个新的EggArray中

public EggArray Map(EggArray.IterationVauleHandler handler)

{

    EggArray targetArray = new EggArray(this.capacity);

    for(int i = 0; i < this.count; i++)

    {

        T t = handler(this.items[i]);

        targetArray.Add(t);

    }

    return targetArray;

}

在EggArrayTest中App开发培训实现Test_Map这个方法:

void Test_Map()

{

    EggArray 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:

调用了Filter方法,其中Filter方法的参数是一个IterationBoolHandler委托,即一个返回bool值的委托。具体可以看Filter的实现。

///

/// Difference the specified others.

///输出不包含others中元素的EggArray

///

/// Others.

public EggArray Difference(EggArray others)

{

    EggArray targetArray = new EggArray();

    targetArray = 

    this.Filter(delegate(T item) {

        bool b = !others.Contains(item);

        return b;

    });

    return targetArray;

}

在EggArrayTest中实现Test_Difference这个方法:

//作为参数传入的EggArray由testArray的第5,第9这2个元素组成

void Test_Difference()

{

    EggArray differentArray = new EggArray();

    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这两个name

 

Invoke:

EggArray的每个元素上执行methodName方法。

///

/// Invoke the specified methodName.

/// 每个元素上执行methodName方法,若方法不存在则抛出exception

///

/// Method name.

public void Invoke(string methodName)

{

    Type t = typeof(T);

    var method = t.GetMethod(methodName);

    if(method == null)

        throw new Exception("没有找到指定的方法哦~,可能不叫" + methodName);

    for(int i = 0; i < this.count; i++)

    {

        method.Invoke(this.items[i], null);

    }

 

}

//调用TargetClass的HI()方法

void Test_Invoke()

{

    testArray.Invoke("Hi");

}

 

 

 

//输出:say hi

 

Pluck:

常州网站开发培训萃取EggArray中某字段值,返回一个数组,由于字段类型不确定,所以需要装箱。当传入的名称无法查找到该字段时,抛出exception。

///

/// Pluck the specified fieldName.

/// 萃取某字段值,返回一个数组

/// 由于字段类型不确定,所以需要装箱

///

/// Field name.

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("没有找到指定的field哦~,可能不叫" + fieldName);

    for(int i = 0; i < this.count; i++)

    {

        object value = field.GetValue(this.items[i]);

        targetArray[i] = value;

    }

    return targetArray;

}

//获取各个元素 字段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:

返回一个随机乱序的T[],下面看代码

///

/// Shuffle this instance.

/// 返回一个随机乱序的副本

///

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;

}

//

void Test_Shuffle()

{

    TargetClass[] test = testArray.Shuffle();

    for(int i = 0; i < test.Length; i++)

    {

        Debug.Log (test[i].name);

    }

}

 

 

//默认顺序为NO. 0 ~ NO. 9

 

//乱序后,见图

 


上篇:上一篇:常州手游开发-简单虚拟摇杆控制移动
下篇:下一篇:常州手游开发-Unity3D中常用的数据结构