如何创建唯一的字符串/键表单JavaScript对象?

如何创建唯一的字符串/键表单JavaScript对象?,javascript,stringify,Javascript,Stringify,我想从对象的值创建一个唯一的字符串/键/标识符/哈希。例如: let myObj = { key1: 'val1', key2: 'val2', key3: 'val3', key4: 'val4' }; function getObjectUniqueKey(obj) { return (`${ obj.key1 }|${ obj.key2 }|${ obj.key3 }|${ obj.key4 }`); } 方法getObjectUniqueKey()可以正常工作,但

我想从对象的值创建一个唯一的字符串/键/标识符/哈希。例如:

let myObj =
{
  key1: 'val1',
  key2: 'val2',
  key3: 'val3',
  key4: 'val4'
};

function getObjectUniqueKey(obj) {
  return (`${ obj.key1 }|${ obj.key2 }|${ obj.key3 }|${ obj.key4 }`);
}
方法
getObjectUniqueKey()
可以正常工作,但是它不能扩展到更大的对象(我的对象有10多个键)

JavaScript中有没有办法创建表示对象的唯一字符串?类似于
JSON.stringify()
的东西,但不是那么健壮吗?
JSON.stringify
也将字符串化键,但我的所有对象都有相同的接口-相同键的名称-因此不需要字符串化它们)

  • {key:'val1'}
    {key:'val2'}
    应产生不同的结果
  • {key1:'val'}
    {key2:'val'}
    应产生不同的结果
  • {a:1,b:2}
    {b:2,a:1}
    应该产生相同的结果

  • 您可以创建所有键的排序数组(以确保比较具有相同键的值),然后将这些键映射到相关值,并在值数组上使用
    JSON.stringify

      JSON.stringify(
        Object.keys(obj)
        .sort()   
        .map(k => obj[k])
     )
    

    这里有两个没有JSON.stringify的示例:

    版本1

    var myObj=
    {
    键1:‘val2’,
    键2:‘val1’,
    键4:‘val4’,
    键3:‘val3’,
    };
    /**
    *获取唯一字符串(版本1)。
    *如果每个对象始终具有相同的关键点,则这是很好的。
    */
    函数getObjectUniqueKey(obj){
    var-res='';
    常量键=对象键(obj);
    keys.sort()
    .forEach((键,i)=>{
    res+=obj[键]
    如果(key.length!=i+1){
    res+='|'
    }
    });
    返回res;
    }
    
    log(`Version1:${getObjectUniqueKey(myObj)}`)如果您希望生成相同的哈希值,而不考虑键顺序,则最有可能需要排序。如果您不想为大型对象使用长得离谱的键,则需要进行某种有损哈希。注意,为了完全散列对象,我们需要能够散列对象中的每种类型的值。下面的逻辑主要使用
    lossyHashStrs
    对字符串数组进行散列。它还可以通过将所有键和值收集到一个数组中,将对象转换为字符串数组。如上所述,对象中的每个值都需要可散列。下面的代码处理字符串、数字和对象值。例如,如果对象包含一个数组作为属性,它将阻塞(但可以扩展以处理此问题!)

    总的来说,散列将是显示为12位十进制数字的字符串,必要时带有前导零

    //用于检查变量类型的实用函数
    设isType=(v,type)=>(v==null&&type==null)| | v.constructor==type;
    让lossyHashStrs=strs=>{
    //将字符串数组转换为看起来像12位数字的字符串
    设max=9999999999;
    设n1=129837378393;
    设n2=348973984723;
    for(让str of strs){//在所有字符串上循环。。。
    对于(设i=0;i{
    //将对象转换为字符串数组,然后返回'lossyHashStrs'结果
    设VAL=[];
    让keys=Object.keys(obj.sort();
    对于(让钥匙中的钥匙){
    VAL.push(按键);
    设val=obj[key];
    //确保“val”可以转换为字符串:
    //如果'val'已经是一个字符串,那么就不必进退两难了!
    if(isType(val,String))vals.push(val);
    //如果“val”是一个数字,只需使用“toString”`
    else if(isType(val,Number))vals.push(val.toString());
    //如果“val”是一个对象,则递归调用“lossyHashObj”(是-循环引用将无限重复)
    else if(isType(val,Object))vals.push(lossyHashObj(val));
    //待办事项:
    //否则如果(isType(val,数组))/**/
    //为任何其他类型的值引发错误
    else抛出新错误(`Object包含一个${val.constructor.name};不知道如何散列:(`);
    }
    返回损失哈希值(VAL);
    };
    让测试=[
    [{a:1},{a:1}],
    [{a:1},{a:2}],
    [{a:1,b:1},{a:1,b:1}],
    [{a:1,b:2},{a:2,b:1}],
    [{a:2,b:3},{b:3,c:4}],
    [{c:3,b:2,a:1},{a:1,b:2,c:3}]
    ]
    对于(让[v1,v2]个测试){
    设hash1=lossyHashObj(v1);
    设hash2=lossyHashObj(v2);
    console.log([
    `比较:`,
    `${JSON.stringify(v1)}(哈希:${hash1})`,
    `${JSON.stringify(v2)}(哈希:${hash2})`,
    `哈希匹配:${(hash1==hash2.toString().toUpperCase()}`
    ].join('\n');
    
    }
    您可以执行
    JSON.stringify(myObj)
    并替换除数字和字母以外的不必要的内容
    str.replace(/[\W\D]/g',)
    @jonaswillms-我更新了我的问题,
    JSON的问题是,stringify
    也会对键进行stringify,如果您只需要在ram中唯一地映射对象,最好只需执行
    让m=newmap();m.set(myObj,'someCorrespondingValue');m.set(anotherObj,'anotherCorrespondingValue)
    通过键计算对象的值对您来说很重要还是唯一很重要?是否应该
    {key:'val1'}
    {key:'val2'}
    生成相同的哈希?是否应该
    {a:1,b:2}
    {b:2,a:1}
    生成相同的哈希?是否应该
    {key1:'val'}
    {key2:'val'}
    产生相同的哈希??