2017-08-05 5 views
2

Ich rufe einen Dienst, der eine Liste von Fragen zurückgibt. Dann gruppiere ich diese Frage nach Themen neu. ich habe diese Umwandlung:Konvertieren Array von Objekten (Art von groupby)

var questions = [ 
 
    { 
 
    id: 1, 
 
    label: 'lorem ispum ?', 
 
    theme: { 
 
     id: 1, 
 
     label: 'dog', 
 
    } 
 
    }, 
 
    { 
 
    id: 2, 
 
    label: 'lorem ispum2 ?', 
 
    theme: { 
 
     id: 2, 
 
     label: 'horse', 
 
    } 
 
    }, 
 
    { 
 
    id: 3, 
 
    label: 'lorem ispum3 ?', 
 
    theme: { 
 
     id: 1, 
 
     label: 'dog', 
 
    } 
 
    }, 
 
]; 
 

 
var groupByTheme = questions.reduce(function(obj,item){ 
 
    obj[item.theme.label] = obj[item.theme.label] || []; 
 
    obj[item.theme.label].push(item); 
 
    return obj; 
 
}, {}); 
 

 
/*var result = Object.keys(groupsByTheme).map(function(key){ 
 
    return {theme: key, questions: groupsByTheme[key]}; 
 
}); 
 
*/ 
 

 
var result = Object.entries(groupByTheme).map(([theme, questions]) => ({ theme, questions })); 
 

 
console.log(result);

Es funktioniert. Aber jetzt möchte ich eine Eigenschaft hinzufügen: die ID des Themas.

{ 
    "themeId": 1, 
    "theme": "dog", 
    "questions": [...] 
}, 
{ 
    "themeId": 2, 
    "theme": "horse", 
    "questions": [...] 
} 

Ich finde nicht den richtigen Weg ohne einen Missy Code.

Irgendwelche Vorschläge? Vielen Dank im Voraus!

Antwort

0

Sie können die fehlenden Teile vergrößern, indem Sie das Ergebnis in der letzten Phase festlegen.

Ich habe den Schlüssel von theme zu id geändert, weil id mehr einzigartig aussieht.

var questions = [{ id: 1, label: 'lorem ispum ?', theme: { id: 1, label: 'dog' } }, { id: 2, label: 'lorem ispum2 ?', theme: { id: 2, label: 'horse' } }, { id: 3, label: 'lorem ispum3 ?', theme: { id: 1, label: 'dog' } }], 
 
    groupByTheme = questions.reduce(function (obj, item) { 
 
     obj[item.theme.id] = obj[item.theme.id] || []; 
 
     obj[item.theme.id].push(item); 
 
     return obj; 
 
    }, {}), 
 
    result = Object.entries(groupByTheme).map(([id, questions]) => ({ 
 
     id, 
 
     theme: questions[0].theme.label,        // add this 
 
     questions 
 
    })); 
 

 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

oh ja, ich fühle mich wie dumm :) Zu lang konzentrierte sich auf das gleiche Problem ^^ –

0

Ich würde Ihnen empfehlen, für die lodash Bibliothek zu verwenden. Dann wird der Code ziemlich sauber sein. Ich werde zunächst die themeMap Objekt machen, die Karte label-id sein würde, wie:

const themeMap = {}; 
_.forEach(questions, question => themeMap[question.theme.label] = question.theme.id); 

Dann wir die groupBy und map von lodash und Code wirklich sauber werden wie verwenden:

const result = _.map(_.groupBy(questions, question => question.theme.label), (group, key) => { 
    return {questions: group, theme: key, themeId: themeMap[key]}; 
}); 

Der Code wird weniger chaotisch sein. Wenn Sie lodash nicht verwenden möchten, können Sie groupBy durch reduce Javascript erreichen, das Sie bereits getan haben.

+0

ja, aber ich wollte nicht, diese externe Bibliothek sind nur für einen Fall in meiner Anwendung . Aber danke ! Es kann vielleicht anderen Entwicklern helfen. –

0

Wenn Sie die Fragen nach dem Namen des Themas gruppieren, können Sie das genaue "Thema" -Objekt erstellen, das Sie möchten { "themeId": 1, "theme": "dog", "questions": [] }, und schieben Sie die Frage in die questions Requisite. Um in Array zu konvertieren, verwenden Sie Object#values.

var questions = [{"id":1,"label":"lorem ispum ?","theme":{"id":1,"label":"dog"}},{"id":2,"label":"lorem ispum2 ?","theme":{"id":2,"label":"horse"}},{"id":3,"label":"lorem ispum3 ?","theme":{"id":1,"label":"dog"}}]; 
 

 
var result = Object.values(// get an array of theme objects 
 
    questions.reduce(function(obj,item){ 
 
     obj[item.theme.label] = obj[item.theme.label] || 
 
     Object.assign({ questions: [] }, item.theme); // create an object that includes theme data, and an empty array for questions 
 

 
     obj[item.theme.label].questions.push(item); // push into questions 
 

 
     return obj; 
 
    }, {}) 
 
); 
 

 
console.log(result);

Verwandte Themen