簡體   English   中英

嘗試遞歸 hash 中的值 object

[英]Trying to recursively hash values in object

朋友們。 我正在嘗試編寫對 JSON 文件中的所有值進行哈希處理的代碼,而不管文件結構如何,同時保留鍵和結構。 我是 javascript 的新用戶,遇到了一些麻煩。 我的代碼對 big 和 baz 的值進行哈希處理,但沒有像我希望的那樣遞歸 hash cat 和 bar 的值。 理想情況下,我希望對數字進行哈希處理並保留名稱(big、foo 等)。 非常感謝:請參閱下面的代碼:

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

如果您希望以遞歸方式執行此操作,我建議使用通用轉換 function 處理遞歸 object 結構並將轉換葉節點的實際工作委托給提供的 function。

在此版本中, transform function 完成了所有繁重的工作。 它在標量值上調用提供的 function,並在對象和 arrays 上遞歸調用自身,用新值重新創建原始結構。 這是相當可重用的。

我們通過傳遞一個 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>

斯科特的回答很棒。 可選的鏈接運算符?. , 現在大多數地方都支持,並且對運行時類型檢查特別有用。 我分享這篇文章是為了查看使用此現代功能表達的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"
      ]
    }
  }
}

這種方法的一個明顯優勢是ArrayObject分支可以以任何順序出現。 使用Array.isArray(t)時,必須在檢查Object(t) === t之前檢查它。 這是一件微妙的事情,但值得注意 -

// 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)
  }
}

您可能還希望 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

一切正常,但括號:

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

應該讀:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM