关联数组(也称映射或字典),与普通的数组类似,二者均可存储多个条目。 但与数组的不同之处在于,其可以输入索引或键(即映射键)。

声明关联数组

Link to 声明关联数组

使用大括号 {} 和冒号 : 来声明关联数组

ZenScript
Copy
val myAssocArray = {
    dirt : <minecraft:dirt>,
    gold : <minecraft:gold_ingot>
} as IItemStack[string];

让我们对其进行拆分分析:

  • val myAssocArray = 标准变量声明
  • { 先生,这是一个关联数组!
  • dirt : <minecraft:dirt> 使用 dirt 字符串映射 <minecraft:dirt>
  • , 等下,这还没完
  • gold : <minecraft:gold_ingot> 使用 gold 字符串映射 <minecraft:gold_ingot>
  • } 长官,数组已经写完了!
  • as IItemStack[string];说明这是使用字符串作为键、 IItemStacks 作为值的关联数组。

好的,那么我在使用它们时需要注意些什么呢?

  • Zenscript 中绝大部分数据类型都可以作为键或值。
  • 你无法用变量作为声明数组的键(使用{}的那个),因为这些文本将会被解释成字符串!

引用关联数组中的项

Link to 引用关联数组中的项

访问关联数组中的项,与访问普通数组中的项,方法是同样的:
Array[index]
唯一的不同之处是,关联数组不必要以整型数值作为索引,可用已声明的索引字符串来替代!

ZenScript
Copy

val dirt = <minecraft:dirt>;
val assocArray = {
    <minecraft:dirt> : "这是我"
} as string[IItemStack];

//数组名[索引]
print(assocArray[<minecraft:dirt>]);

//只要类型匹配,这里也可以使用变量。
print(assocArray[dirt]);

有一种特殊情况,当索引为字符串时:
使用 memberGetter 方法(见下)就可以直接引用项:

ZenScript
Copy
val assocWithStrings = {
    //你可以使用 ""
    "one" : "1",

    //但这不是强制的
    two : "2"
} as string[string];

//你既可以使用 memberGetter
print(assocWithStrings.one);

//也可以使用传统的索引
print(assocWithStrings["two"]);

修改关联数组中的项

Link to 修改关联数组中的项

与数组一样,可以使用 array[index] = newValue 来修改关联数组中的项.
但有一个主要的区别:
数组存在长度限制,映射则不存在。 这意味着你随时可以通过向数组中添加先前并不包含的索引来添加新的项!

ZenScript
Copy
val changingArray = {
    <minecraft:dirt> : "这是我",
    <minecraft:gold_ingot> : "我讨厌它"
} as string[IItemStack];

val gg = <minecraft:gold>;

//覆盖 gold_ingot 的值
changingArray[gg] = "我爱它";

//添加新条目
changingArray[<minecraft:grass>] = "能量!";

检索关联数组的键集和项集

Link to 检索关联数组的键集和项集

键集(KeySet)是一个包含了所有映射的键的数组。
项集(valueSet)是一个包含了所有映射的项的数组。
条目集(entrySet)是一个包含了所有映射条目的数组(见下)。

ZenScript
Copy
myAssocArray.keySet   //键集
myAssocArray.keys     //键集
myAssocArray.values   //项集
myAssocArray.valueSet //项集
myAssocArray.entrySet //条目集

遍历一个关联数组

Link to 遍历一个关联数组

这里提供了两种遍历方法来遍历关联数组:

  • 键遍历法:遍历所有的键,只需要传入一个参数
  • 键-值遍历法:同时遍历键和值,需要传入两个参数

让我们来遍历一个存储了工作台配方的关联数组:

  • 键作为的配方的输出,类型为 物品堆(IItemStack)
  • 值作为配方的输入,类型为 材料(IIngredient)
  • 我们将使用如下所示的键迭代器: for key in assocArray {代码;}
  • 我们也可以使用如下所示的键-值迭代器: for key, value in assocArray {代码;}
ZenScript
Copy
import crafttweaker.item.IItemStack;
import crafttweaker.item.IIngredient;

val dirt = <minecraft:dirt>;
val recipeMapShaped = {
    <minecraft:grass> : [[dirt, dirt, dirt],[dirt, dirt, dirt],[dirt, dirt, dirt]],
    <minecraft:gold_ingot> : [[dirt, dirt, dirt],[dirt, <minecraft:gold_ingot>, dirt],[dirt, dirt, dirt]]
} as IIngredient[][][IItemStack];

recipeMapShaped[dirt] = [[dirt, dirt, dirt],[dirt, null, dirt],[dirt, dirt, dirt]];

//键是 草(grass)、金锭(goldIngot)和泥土(dirt)
for key in recipeMapShaped {
    recipes.addShaped(key, recipeMapShaped[key]);
}


//键是 草(grass)、金锭(goldIngot)和泥土(dirt),值是 他们各自的配方
for key, value in recipeMapShaped {
    recipes.addShaped(key, value);
}

一个映射项包含一组键-值。
目前仅能通过映射的 entrySet 方法获取此条目。

你可以使用 getters 来具体获取其中的

ZenScript
Copy
//从已有的映射/关联数组获取映射条目
val myEntry = map.entrySet[0];


myEntry.key;    //返回条目的键。
myEntry.value;  //返回该条目的值。