我有一个对象或对象数组,道具包含字符串,数组和其他对象。
我想将包含带有道具language
的对象的嵌套数组转换为以language
为键且对象本身为prop的对象。
给出对象:
{
"id": 1,
"title": "First",
"ProjectsTranslations": [ // This one
{
"id": 1,
"language": "en"
},
{
"id": 2,
"language": "de"
}
],
"someObject": {
"someProp1": "Some string1",
"someProp2": "Some string2"
},
"someArray": [
{
"someProp1": "Some string1"
},
{
"someProp1": "Some string1"
}
]
}
我正在尝试将其转换为:
{
"id": 1,
"title": "First",
"ProjectsTranslations": {
// This one
"en": {
"id": 1,
"language": "en"
},
"de": {
"id": 2,
"language": "de"
}
},
"someObject": {
"someProp1": "Some string1",
"someProp2": "Some string2"
},
"someArray": [
{
"someProp1": "Some string1"
},
{
"someProp1": "Some string1"
}
]
}
给出数组:
[
{
"id": 1,
"title": "First",
"ProjectsTranslations": [
{
"id": 1,
"language": "en"
},
{
"id": 2,
"language": "de"
}
]
},
{
"id": 1,
"title": "Second",
"ProjectsTranslations": [
{
"id": 1,
"language": "en"
},
{
"id": 2,
"language": "de"
}
]
}
]
进入:
[
{
"id": 1,
"title": "First",
"ProjectsTranslations": {
"en": {
"id": 1,
"language": "en"
},
"de": {
"id": 1,
"language": "de"
}
}
},
{
"id": 2,
"title": "Second",
"ProjectsTranslations": {
"en": {
"id": 1,
"language": "en"
},
"de": {
"id": 1,
"language": "de"
}
}
},
]
我一直在试图找到一种方法,但是似乎很困难。有什么建议吗?我正在尝试不使用Lodash或Underscore。
编辑
我找到了一种方法,但是这并不是我想要的。我递归检查所有对象,如果其中一个是数组,并且其名称包含字符串translations
,则从那里开始操作。但这需要一个命名约定-所有可翻译模型的名称都应带有Translations
-我不喜欢。这是功能,但是如果有解决方案,可以检查lang值,那么就好。
export const transformTranslatedData = function(data) {
var clonedData = JSON.parse(JSON.stringify(data));
const transform = function(data) {
for (const prop in data) {
if (data[prop] instanceof Array && prop.includes('Translations')) {
data[prop] = data[prop].reduce(function(prev, current, index) {
prev[current.language] = current;
return prev;
}, {});
}
if (data[prop] instanceof Object && !(data[prop] instanceof Array)) {
transformTranslatedData(data[prop]);
}
}
return data;
};
// Check if its an Array; if it is, iterate over it and push transformed objects into new array.
if (clonedData instanceof Array) {
var newData = [];
clonedData.map((item) => {
newData.push(transform(item));
});
} else if (clonedData instanceof Object && !(clonedData instanceof Array)) {
var newData = {};
newData = transform(clonedData);
}
return newData;
};
编辑2
我设法检查数组中对象的属性。如此简单:
data[prop] instanceof Array && data[prop].length > 0 && data[prop][0].hasOwnProperty('language')
最终功能是:
export const transformTranslatedData = function(data) {
var clonedData = JSON.parse(JSON.stringify(data));
const transform = function(data) {
for (const prop in data) {
if (data[prop] instanceof Array && data[prop].length > 0 && data[prop][0].hasOwnProperty('language')) {
data[prop] = data[prop].reduce(function(prev, current, index) {
prev[current.language] = current;
return prev;
}, {});
}
if (data[prop] instanceof Object && !(data[prop] instanceof Array)) {
transformTranslatedData(data[prop]);
}
}
return data;
};
if (clonedData instanceof Array) {
var newData = [];
clonedData.map((item) => {
newData.push(transform(item));
});
} else if (clonedData instanceof Object && !(clonedData instanceof Array)) {
var newData = {};
newData = transform(clonedData);
}
return newData;
};
但是有点脏……
答案 0 :(得分:0)
您可以使用数组中的reduce函数。
reduce遍历数组,并将结果聚合到您的第一个参数中(在我们的例子中为agg
)。
最后,const result = { ...obj, ProjectsTranslations: newProjectTranslation }
用我创建的新内容覆盖了ProjectsTranslations
来自MDN:
reduce()方法在数组的每个成员上执行reducer函数(由您提供),从而产生单个输出值。
const obj = {
"id": 1,
"title": "First",
"ProjectsTranslations": [ // This one
{
"id": 1,
"language": "en"
},
{
"id": 2,
"language": "de"
}
],
"someObject": {
"someProp1": "Some string1",
"someProp2": "Some string2"
},
"someArray": [
{
"someProp1": "Some string1"
},
{
"someProp1": "Some string1"
}
]
}
getModifiedObject = (someObject, key) => {
let ProjectsTranslations = someObject.ProjectsTranslations
const newProjectTranslation = ProjectsTranslations.reduce((agg, item) => {
const lang = item[key]
agg[lang] = item
return agg
}, {})
return { ...obj, ProjectsTranslations: newProjectTranslation }
}
console.log(getModifiedObject(obj, 'language'))
答案 1 :(得分:0)
尝试一下,可能会对您有所帮助
var obj1= {
"id": 1,
"title": "First",
"ProjectsTranslations": [ // This one
{
"id": 1,
"language": "en"
},
{
"id": 2,
"language": "de"
}
],
"someObject": {
"someProp1": "Some string1",
"someProp2": "Some string2"
},
"someArray": [
{
"someProp1": "Some string1"
},
{
"someProp1": "Some string1"
}
]
};
transformObject(obj1,"ProjectsTranslations");
function transformObject(obj1,arrayKey){
var ProjectsTranslationsObj ={};
for (var i=0;i< obj1[arrayKey].length;i++){
var key =obj1[arrayKey][i].language;
ProjectsTranslationsObj[key] = obj1[arrayKey][i];
};
obj1[arrayKey] = ProjectsTranslationsObj;
}
答案 2 :(得分:0)
创建了一个函数changeProjectsTranslations
,用于将数组更改为对象。
function changeProjectsTranslations(obj) {
/*
let obj = {
"id": 1,
"title": "First",
"ProjectsTranslations": [
{
"id": 1,
"language": "en"
},
{
"id": 2,
"language": "de"
}
]
}
*/
let oldLanguage = obj.ProjectsTranslations,
newLanguage = {};
for(let o of oldLanguage) {
newLanguage[o.language] = o;
}
obj.ProjectsTranslations = newLanguage;
return obj;
}
let array = [
{
"id": 1,
"title": "First",
"ProjectsTranslations": [
{
"id": 1,
"language": "en"
},
{
"id": 2,
"language": "de"
}
]
},
{
"id": 1,
"title": "Second",
"ProjectsTranslations": [
{
"id": 1,
"language": "en"
},
{
"id": 2,
"language": "de"
}
]
}
];
for (let i = 0; i < array.length; i++) {
array[i] = changeProjectsTranslations(array[i]);
}
console.log(array);