我需要存储数据来表示这个:
水 + 火 = Steam
水+土=泥
泥 + 火 = 岩石
目标如下:我有可拖动的 HTML div,当 <div id="Fire">
和 <div id="Mud">
重叠,我添加 <div id="Rock">
到屏幕。曾经在 iPhone 或 Android 上玩过 Alchemy 吗?同样的东西
现在,我这样做的方式是一个 JS 对象:
var stuff = {
'Steam' : { needs: [ 'Water', 'Fire'] },
'Mud' : { needs: [ 'Water', 'Earth'] },
'Rock' : { needs: [ 'Mud', 'Fire'] },
// etc...
};
每次一个 div 与另一个 div 重叠时,我都会遍历对象键并检查“需要”数组。
我可以处理该结构,但我想知道我是否可以做得更好?
编辑:我应该补充一点,我还需要存储一些其他内容,例如简短描述或图标名称。所以通常我有 Steam: { needs: [ array ], desc: "short desc", icon:"steam.png"},
最终编辑:感谢大家的贡献,我发现你们所有的评论都非常有值(value)
最佳答案
如果您不介意包含另一个外部库并且熟悉 LINQ,您可以使用 linq.js为了这。
var stuff = {
'Steam' : { needs: ['Water', 'Fire'] },
'Mud' : { needs: ['Water', 'Earth'] },
'Rock' : { needs: ['Mud', 'Fire'] }
// etc...
};
function Alchemy(stuff) {
var recipes =
Enumerable.From(stuff).ToLookup(
"$.Value.needs",
"$.Key",
"Enumerable.From($).OrderBy().ToString('+')"
);
this.attempt = function(elem1, elem2) {
return recipes.Get([elem1, elem2]).ToString();
};
};
var alchemy = new Alchemy(stuff);
console.log(alchemy.attempt('Fire', 'Mud')); // "Rock"
console.log(alchemy.attempt('Fire', 'Earth')); // ""
console.log(alchemy.attempt('Fire', 'Water')); // "Steam"
注释
Enumerable.From(stuff)
将您的stuff
对象拆分为其Key
和Value
部分。
例如,Key
将引用"Rock"
,Value
将引用{ needs: ['Mud', 'Fire'] }
。ToLookup()
从中创建一个查找字典。它需要3个参数:- 寻找什么(在本例中,
"$.Value.needs"
中的元素) - 如果找到匹配项返回什么(在本例中,结果元素的名称,即
Key
) - 创建字典键的转换函数(在本例中,成分数组转换为排序字符串:
['Mud', Fire']
变为"Fire+Mud"
).
- 寻找什么(在本例中,
Get()
函数使用相同的转换函数为其参数找到匹配项。
请注意,像 "$.Value.needs"
这样的字符串参数是
的简写
function ($) { return $.Value.needs;
。
linq.js 还提供了 many more useful functions可以将复杂的任务转化为一行。
编辑:从查找中返回所有附加信息将非常简单:
function Alchemy(stuff) {
var recipes =
Enumerable.From(stuff).ToLookup(
"$.Value.needs",
null, // return the object unchanged
"Enumerable.From($).OrderBy().ToString('+')"
);
this.attempt = function(elem1, elem2) {
return recipes.Get([elem1, elem2]).FirstOrDefault();
};
};
console.log(alchemy.attempt('Fire', 'Mud'));
/* result
{
Key: "Rock",
Value: {
needs: ["Mud", "Fire"],
whatever: "else you had defined in {stuff}"
}
}
*/
Lookup 对象的目的是提高速度。您也可以每次都遍历整个对象图:
function alchemy(elem1, elem2) {
return
Enumerable
.From(stuff)
.Where(function ($) {
var recipe = Enumerable.From($.Value.needs);
return recipe.Intersect([elem1, elem2]).Count() == 2;
})
.Select("{element: $.Key, properties: $.Value}")
.FirstOrDefault();
);
console.log(alchemy('Fire', 'Water'));
// {element: "Steam", properties: {needs: ["Water", "Fire"]}}
请注意,.Select()
是可选的。您可以删除它,在这种情况下,结果将与前面的示例相同。
关于javascript - 在 Javascript 中存储树数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13273053/