3 回答

TA貢獻2051條經驗 獲得超10個贊
如果您希望以遞歸方式執行此操作,我建議使用通用轉換函數來處理遞歸對象結構并將轉換葉節點的實際工作委托給提供的函數。
在此版本中,該transform函數完成了所有繁重的工作。它對標量值調用提供的函數,并在對象和數組上遞歸地調用自身,使用新值重新創建原始結構。這是非??芍貜褪褂玫?。
我們通過傳遞一個對我們的值進行 sha256 編碼的函數來創建我們的hashObject函數。transform
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/[email protected]/src/sha256.js"></script>

TA貢獻1845條經驗 獲得超8個贊
現在在大多數地方都受支持,并且對于運行時類型檢查特別有用。我分享這篇文章是為了了解如何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/[email protected]/src/sha256.js"></script>
{
? "big": "f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b",
? "baz": {
? ? "foo": {
? ? ? "cat": "4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce",
? ? ? "bar": "ef2d127de37b942baad06145e54b0c619a1f22327b2ebbcfbec78f5564afe39d",
? ? ? "qux": [
? ? ? ? "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
? ? ? ? "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35",
? ? ? ? "4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce"
? ? ? ]
? ? }
? }
}
這種方法的一個明顯優點是Array和Object分支可以以任何順序出現。使用時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這是使用泛型函數實現泛型的一種可能性traverse-
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/[email protected]/src/sha256.js"></script>
2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
492f06976c8bc705819f5d33d71be6a80a547b03f87c377e3543605d8260159c
492f06976c8bc705819f5d33d71be6a80a547b03f87c377e3543605d8260159c
d1ae8b8641d3d6d65b1e4eecab0484a9f9618f2aabafe473c8bb0b4f6382695c
d1ae8b8641d3d6d65b1e4eecab0484a9f9618f2aabafe473c8bb0b4f6382695c

TA貢獻2036條經驗 獲得超8個贊
一切都好,但括號:
if(typeof(obj[vaz] != "object"))
應該讀:
if(typeof(obj[vaz]) != "object")
添加回答
舉報