如何创建唯一的字符串/键表单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'}
产生相同的哈希??