简体   繁体   English

尝试递归 hash 中的值 object

[英]Trying to recursively hash values in object

friends.朋友们。 I'm trying to write code that hashes all values in a JSON file, regardless of file structure, while preserving the keys and structure.我正在尝试编写对 JSON 文件中的所有值进行哈希处理的代码,而不管文件结构如何,同时保留键和结构。 I'm new to javascript, and am having some trouble.我是 javascript 的新用户,遇到了一些麻烦。 My code hashes the values of big and baz, but doesn't recursively hash the values of cat and bar like I want it to.我的代码对 big 和 baz 的值进行哈希处理,但没有像我希望的那样递归 hash cat 和 bar 的值。 Ideally, I want the numbers hashed and the names (big, foo, etc.) left alone.理想情况下,我希望对数字进行哈希处理并保留名称(big、foo 等)。 Thank you so much: See my code below:非常感谢:请参阅下面的代码:

var meow = {
  big: 20,
  baz: {
    foo: {
      cat: 3,
      bar: 5

    }
  }
};

console.log(typeof(meow.baz.foo));

function hashobj(obj)
{
    var valarray = Object.keys(obj);
    var zer = valarray[0];
    for(var i = 0; i < valarray.length; i++)
    {
        var vaz = valarray[i];
        if(typeof(obj[vaz] != "object"))
        {
            obj[vaz] = sha256(obj[vaz] + buf);
        }
        if(typeof(obj[vaz]) == "object")
        {
            console.log("HERE");
            hashobj(obj[vaz]);
        }
    }
}
hashobj(meow);
console.log(meow);

If you're looking to do this recursively, I would suggest using a generic transformation function that handles the recursive object structure and delegates to a supplied function the actual work of transforming the leaf nodes.如果您希望以递归方式执行此操作,我建议使用通用转换 function 处理递归 object 结构并将转换叶节点的实际工作委托给提供的 function。

In this version, the transform function does all the heavy lifting.在此版本中, transform function 完成了所有繁重的工作。 It calls the supplied function on scalar values and recursively calls itself on objects and arrays, recreating the structure of the original with the new values.它在标量值上调用提供的 function,并在对象和 arrays 上递归调用自身,用新值重新创建原始结构。 This is quite reusable.这是相当可重用的。

We create our hashObject function by passing transform a function which does the sha256 encoding of our values.我们通过传递一个 function transform来创建我们的hashObject function,它对我们的值进行 sha256 编码。

 const transform = (fn) => (obj) => Array.isArray (obj)? obj.map (transform (fn)): Object (obj) === obj? Object.fromEntries (Object.entries (obj).map (([k, v]) => [k, transform (fn) (v)]) ): fn (obj) const hashObj = transform ((n) => sha256 (String (n))) const meow = {big: 20, baz: {foo: {cat: 3, bar: 5, qux: [1, 2, 3]}}}; // added to demonstrate arrays --------^ console.log (hashObj (meow))
 .as-console-wrapper {max-height: 100%;important: top: 0}
 <script src="https://unpkg.com/js-sha256@0.9.0/src/sha256.js"></script>

Scott's answer is wonderful.斯科特的回答很棒。 The optional chaining operator , ?. 可选的链接运算符?. , is supported most places now and is particularly useful for runtime type checking. , 现在大多数地方都支持,并且对运行时类型检查特别有用。 I'm sharing this post as a way to see transform expressed using this modern feature -我分享这篇文章是为了查看使用此现代功能表达的transform -

 function transform (f, o) { switch (o?.constructor) // <- any o, even null and undefined { case Array: return o.map(_ => transform(f, _)) case Object: return Object.fromEntries ( Object.entries(o).map(([k, _]) => [k, transform(f, _)]) ) default: return f(o) } } const result = transform ( _ => sha256(String(_)), {big: 20, baz: {foo: {cat: 3, bar: 5, qux: [1, 2, 3]}}} ) console.log(result)
 .as-console-wrapper {max-height: 100%;important: top: 0}
 <script src="https://unpkg.com/js-sha256@0.9.0/src/sha256.js"></script>

{
  "big": "f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b",
  "baz": {
    "foo": {
      "cat": "4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce",
      "bar": "ef2d127de37b942baad06145e54b0c619a1f22327b2ebbcfbec78f5564afe39d",
      "qux": [
        "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
        "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35",
        "4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce"
      ]
    }
  }
}

One distinct advantage to this approach is the Array and Object branches can appear in any order.这种方法的一个明显优势是ArrayObject分支可以以任何顺序出现。 When using Array.isArray(t) it must be checked before checking Object(t) === t .使用Array.isArray(t)时,必须在检查Object(t) === t之前检查它。 It's a subtle thing but is worth noting -这是一件微妙的事情,但值得注意 -

// also correct!

function transform (f, o)
{ switch (o?.constructor)
  { case Object:                   // <- type-check Object
      return // ...
    case Array:                    // <- type-check Array
      return // ...
    default:
      return f(o)
  }
}

You may also wish to hash an entire object. Here's one possibility to implement a generic hash using a generic traverse function -您可能还希望 hash 整个 object。这是使用通用traverse function 实现通用hash的一种可能性 -

 function* traverse (t, r = []) { switch (t?.constructor) // <- any t, even null and undefined { case Array: case Set: case Map: for (const [k, _] of t.entries()) yield* traverse(_, [...r, k]) break case Object: for (const [k, _] of Object.entries(t)) yield* traverse(_, [...r, k]) break default: yield [r, t] } } function hash (t) { const r = sha256.create() for (const [k, v] of traverse(t)) r.update(k.concat(v).join(":")) return r.hex() } const input = {big: 20, baz: {foo: {cat: 3, bar: 5, qux: [1, 2, 3]}}} console.log(hash("foo"), hash("foo")) console.log(hash([1,2,3]), hash([1,2,3])) console.log(hash(input), hash(input))
 .as-console-wrapper {max-height: 100%;important: top: 0}
 <script src="https://unpkg.com/js-sha256@0.9.0/src/sha256.js"></script>

2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae

492f06976c8bc705819f5d33d71be6a80a547b03f87c377e3543605d8260159c
492f06976c8bc705819f5d33d71be6a80a547b03f87c377e3543605d8260159c

d1ae8b8641d3d6d65b1e4eecab0484a9f9618f2aabafe473c8bb0b4f6382695c
d1ae8b8641d3d6d65b1e4eecab0484a9f9618f2aabafe473c8bb0b4f6382695c

Everything is ok but the parenthesis:一切正常,但括号:

    if(typeof(obj[vaz] != "object"))

should read:应该读:

    if(typeof(obj[vaz]) != "object")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM