为了账号安全,请及时绑定邮箱和手机立即绑定

尝试递归地散列对象中的值

尝试递归地散列对象中的值

繁花如伊 2023-09-28 09:38:44
朋友们。我正在尝试编写对 JSON 文件中的所有值进行哈希处理的代码,无论文件结构如何,同时保留键和结构。我是 javascript 新手,遇到了一些麻烦。我的代码对 big 和 baz 的值进行哈希处理,但没有像我希望的那样递归地对 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);
查看完整描述

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/js-sha256@0.9.0/src/sha256.js"></script>


查看完整回答
反对 回复 2023-09-28
?
精慕HU

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/js-sha256@0.9.0/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/js-sha256@0.9.0/src/sha256.js"></script>

2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae

2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae


492f06976c8bc705819f5d33d71be6a80a547b03f87c377e3543605d8260159c

492f06976c8bc705819f5d33d71be6a80a547b03f87c377e3543605d8260159c


d1ae8b8641d3d6d65b1e4eecab0484a9f9618f2aabafe473c8bb0b4f6382695c

d1ae8b8641d3d6d65b1e4eecab0484a9f9618f2aabafe473c8bb0b4f6382695c


查看完整回答
反对 回复 2023-09-28
?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

一切都好,但括号:

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

应该读:

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


查看完整回答
反对 回复 2023-09-28
  • 3 回答
  • 0 关注
  • 107 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信