javascript - 在 Javascript 中存储树数据

标签 javascript

我需要存储数据来表示这个:

水 + 火 = 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 对象拆分为其 KeyValue 部分。
    例如,Key 将引用 "Rock"Value 将引用 { needs: ['Mud', 'Fire'] }
  • ToLookup() 从中创建一个查找字典。它需要3个参数:
    1. 寻找什么(在本例中,"$.Value.needs" 中的元素)
    2. 如果找到匹配项返回什么(在本例中,结果元素的名称,即 Key)
    3. 创建字典键的转换函数(在本例中,成分数组转换为排序字符串:['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/

相关文章:

javascript - 更改按钮属性会触发我的表单提交吗?

javascript - 在 Node.js 中从文件末尾读取确定大小的字符串

javascript - 用户在 HTML Javascript 中输入的所有数字的总和

javascript - JSignature 从数据库重新创建签名

javascript - Laravel-Ajax : multiple inputs in 1 form

javascript - res.download() 不适用于我的情况

javascript - 区分具有相同类、id和父类的表行

javascript - 将纯文本转换成<输入类型="text">

javascript - 这个数组的长度如何等于 10?

javascript - 如何在 Puppeteer 中代理特定请求