Javascript:将嵌套对象转换为以值作为路径的对象

Javascript:将嵌套对象转换为以值作为路径的对象,javascript,javascript-objects,Javascript,Javascript Objects,这个问题不是重复的,因为附加值成为键,顺序变化很大,我的对象不是简单的“一行” 我已经更新了问题描述以使其更清楚 我有一个嵌套对象,它表示控制器映射的多语言路径: { "welcome": { "news": { "de": "nachrichten", "en": "news" }, "de": "willkommen", "en": "welcome" }, "applications": { "applicati

这个问题不是重复的,因为附加值成为键,顺序变化很大,我的对象不是简单的“一行”

我已经更新了问题描述以使其更清楚


我有一个嵌套对象,它表示控制器映射的多语言路径:

{
  "welcome": {
    "news": {
      "de": "nachrichten",
      "en": "news"
    },
    "de": "willkommen",
    "en": "welcome"
  },
  "applications": {
    "application1": {
      "de": "anwendung1",
      "en": "application1"
    },
    "application2": {
      "features": {
        "de": "funktionen",
        "en": "features"
      },
      "de": "anwendung2",
      "en": "application2"
    },
    "de": "anwendungen",
    "en": "applications"
  }
}
应将其转换为易于使用的对象,该对象接受路径作为键:

{
  "/de/willkommen/": "welcome",
  "/en/welcome/": "welcome",
  "/de/willkommen/nachrichten/": "news",
  "/en/welcome/news/": "news",
  "/de/anwendungen/": "applications",
  "/en/applications/": "applications",
  "/de/anwendungen/anwendung1/": "application1",
  "/en/applications/application1/": "application1",
  "/de/anwendungen/anwendung2/": "application2",
  "/en/applications/application2/": "application2",
  "/de/anwendungen/anwendung2/funktionen/": "features",
  "/en/applications/application2/features/": "features",

}
现在,特定于语言的初始值(“de”:“willkommen”等)构建了路径,是键,初始键是值。但是请看一看,它有点复杂

我已经构建了一个函数,但它们只适用于第一个级别,如“/de/anwendungen/”,而不适用于“/de/anwendungen/anwendung1/”及更低级别

  convertToPath(OldObject, NewObject = {})
  {
    for(let SecondObject in OldObject)
    {
      for(let Key in OldObject[SecondObject])
      {
        NewObject["/" + Key + "/" + OldObject[SecondObject][Key] + "/"] = SecondObject;
      }
    }

    return NewObject;
  }

那么,您可以通过使用递归来创建对象 数据树,如下所示:

var数据={
“欢迎”:{
“新闻”:{
“de”:“Nachricten”,
“en”:“新闻”
},
“de”:“Willkomen”,
“恩”:“欢迎”
},
“应用程序”:{
“应用程序1”:{
“德”:“安文敦1”,
“en”:“应用程序1”
},
“应用程序2”:{
“特点”:{
“de”:“funktionen”,
“en”:“功能”
},
“德”:“安文敦2号”,
“en”:“应用程序2”
},
“德”:“安文敦根”,
“en”:“应用程序”
}
};
变量langs=['en','de'];
变量路径到控制器=函数(数据、路径、路径){
路径=路径|{};
pathsofar=pathsofar | |{};
Object.keys(数据).forEach(函数(键){
var newpathsofar;
if(langs.some(函数(lang){returnkey==lang;})){
返回;
}
newpathsofar=langs.reduce(函数(p,lang){
p[lang]=pathsofar[lang]| |'/'+lang+/';
p[lang]+=data[key][lang]+'/';
路径[p[lang]]=key;
返回p;
}, {});
路径到控制器(数据[键]、路径、新路径)
});
返回路径;
};
var路径=路径到控制器(数据);
var pre=document.createElement('pre');
pre.innerHTML=JSON.stringify(路径,null,4);

文件.正文.附件(pre)和答案1的轻微替代。虽然我完全同意“暴民之王”的说法,但这种结构是有缺陷的,而且容易出错。如果你需要名为“en”(例如荷兰语中的“AND”意思)的资源,你可以去班塔普杜的小溪

// target hold the desired output
var target = {};

// languages to distinguish between "a translated resource" and "a resource".
var ls = [ "en", "de" ];
var path = [];
var recurse = function(a,n) {
        // can be made pretty by using ls.
        if (a.hasOwnProperty("de") || a.hasOwnProperty("en"))
    {
        path.push(a);
    }
    var keys = Object.keys(a);
    keys.forEach( 
       function(o) { 
        if (ls.indexOf(o) > -1) {
 var spath = path.reduce( function(pV, cV) { return pV + "/" + cV[o]; }, o);
            target[spath] = n;
        } else {
            recurse(a[o], o);
        }
       }
      );
        // can be made pretty by using ls.
    if (a.hasOwnProperty("de") || a.hasOwnProperty("en"))
    {
        path.pop();
    }
};

// your example data.
var source = {..use your example data.};

// start the recursion
recurse( source );

// output the result
JSON.stringify(target);

逻辑似乎很复杂。您能解释一下如何获得第一个JSON对象以及如何使用第二个JSON对象吗?也许,我们可以在处理之前更改一些内容。第一个JSON对象是由用户定义的路由器的定义,它应该具有良好的结构。第二个JSON对象应该由该路由器内部使用,并且应该易于使用,只需将window.location.pathname添加到该对象中即可获得控制器。例如,FirstObject[window.location.pathname]将返回该路由的控制器名称(path)。但是,如果转换效率太低,我们必须将第一个用户定义的json对象更改为非结构化的对象。谢谢!如果您不必在函数中指定每种语言,那就更好了。你有解决这个问题的办法吗?我认为不应该有一个
controllerlang
。相反,控制器是通过属性名称选择的?也就是说,将
数据[key][controllerlang]
交换为一个简单的
。它们等同于英文名称可能只是巧合。@Kiltarc:事实上,编辑是在你的名字出现前3分钟41秒完成的comment@Kiltarc,是的,在您发表评论之前,我已经决定进行更改@伯吉,你说得对。控制器应该是属性名,而不是英文名。在使用中,它们可能会不一样。谢谢!“使用ls”是什么意思。我不知道“ls”是什么。也许您已经可以做得很好了?不必检查显式的“de”和“en”,您可以遍历“ls”数组,查看该条目是否作为属性存在。这样就可以去掉“硬编码的en&de”,并有一个“使用的语言删节列表”。