如果目的/目标是简单的反转(即没有嵌套对象结构;没有多个值),answer from Muhammad imran 是有效的。
显然这是要达到的最佳结果,如果不创建进一步的技巧,以涵盖对象中的键-值关系是:
看看上面的啤酒例子,有点遗憾的是信息在反演中丢失了。因此,这个答案应该补充和丰富并提供一种可以存储信息的方式。实现它的方法是在生成的反转对象中使用 Javascript 数组,以允许 存储潜在的模棱两可的新值。例如。
var BeerAtoB = {
"amore" : "love",
"alimenti": "food",
"Bier" : "beer",
"cerveza" : "beer",
"pivo" : "beer",
"birra" : "beer",
"cerveja" : "beer"
};
允许将 (de,es,pl/cz,it,pt)"beer" 翻译成英文最好存储
这个信息在倒太
var BeerBtoA = {
"love" : "amore",
"food" : "alimenti",
"beer" : [ "Bier" ,
"cerveza",
"pivo",
"birra",
"cerveja"
]
};
一个信息丢失较少的版本,原始值“beer”的多重性通过联合下的值多重性来体现,现在倒置键“beer”。
为了实现这一点,我做了一个增强的反相函数
function invertObject(obj)
{
var invertedObject = {};
// make a stack and prime it with the obj
var stack = [];
stack.push({"way":[],"obj":obj});
// while stuff on the stack
while (stack.length)
{
var way= stack[0].way;
var obj= stack[0].obj;
for (var prop in obj)
{
if (typeof obj[prop] === 'object')
{
// attributes, which are themselves objects are added to the stack,
// with their way information.
stack.push({"way":way.concat(prop),"obj":obj[prop]});
}
else
{
// always start with adding things to the invertedObject,
var curobj = invertedObject;
var value = newKey = obj[prop];
var curpath = way.concat(prop).concat(obj[prop]);
// for all but the last two path elements the loop below
// will create the inverted path, starting with the value (obj[prop])
// as key, Since values need not be unique (as keys), create each
// such new key-property as an Array, not to loose inverted pathes.
while(curpath.length>2)
{
var pathpart = curpath.pop();
if(!curobj.hasOwnProperty(pathpart))
{
curobj[pathpart]=[];
}
curobj=curobj[pathpart];
}
// the last two curpath Array members represent the last key and the
// new to be added value.
var preLastPart = curpath.pop();
var lastPart = curpath.pop();
// Again the artifice of an Array is used since
// the inverted keys are not unique, hence cases in which
// 1 key has (>1) values.
if(!curobj.hasOwnProperty(preLastPart))
{
curobj[preLastPart]=[];
}
curobj[preLastPart].push(lastPart);
}
}
stack.shift();
}
return invertedObject; function invertObject(obj)
{
var invertedObject = {};
// make a stack and prime it with the obj
var stack = [];
stack.push({"way":[],"obj":obj});
// while stuff on the stack
while (stack.length)
{
var way= stack[0].way;
var obj= stack[0].obj;
for (var prop in obj)
{
if (typeof obj[prop] === 'object')
{
// attributes, which are themselves objects are added to the stack,
// with their way information.
stack.push({"way":way.concat(prop),"obj":obj[prop]});
}
else
{
// always start with adding things to the invertedObject,
var curobj = invertedObject;
var value = newKey = obj[prop];
var curpath = way.concat(prop).concat(obj[prop]);
// for all but the last two path elements the loop below
// will create the inverted path, starting with the value (obj[prop])
// as key, Since values need not be unique (as keys), create each
// such new key-property as an Array, not to loose inverted pathes.
while(curpath.length>2)
{
var pathpart = curpath.pop();
if(!curobj.hasOwnProperty(pathpart))
{
curobj[pathpart]=[];
}
curobj=curobj[pathpart];
}
// the last two curpath Array members represent the last key and the
// new to be added value.
var preLastPart = curpath.pop();
var lastPart = curpath.pop();
// Again the artifice of an Array is used since
// the inverted keys are not unique, hence cases in which
// 1 key has (>1) values.
if(!curobj.hasOwnProperty(preLastPart))
{
curobj[preLastPart]=[];
}
curobj[preLastPart].push(lastPart);
}
}
stack.shift();
}
return invertedObject;
}
}
事实上,由于在简单和嵌套对象的许多地方都可以找到相等的值,因此结果将是一个对象,其中每个值都是一个数组,原因有两个:
多个原始对象的键可以具有相同的值,因此(反转后)可以存在多个值。一个数组可以存储所有这些多个新值,因此可以存储所有信息。
在嵌套对象中,唯一性使得每个属性要么是直接值,要么是子对象,在键的反转对象中,我们不仅可以找到多个值,还可以在同一位置找到多个值也是进一步嵌套的对象。 (出于这个原因,幸运的是,作为对象的 Javascript 数组除了其条目之外还允许附加更多属性,因此可以同时用作多个值的存储和嵌套中的子键结构。这种倒置对象结构中的数组的双重用途,不幸的是,很难用 JSON 表示法显示,如 JSON notation does not allow for Arrays with Object Attributes)