param { List < Article > } articles param { string } level param { Article } newArticle return { List < Article > } function editArticleInList ( articles , level , newArticle ) { return articles . map ( ( article ) => { const articleLevel = article . getLevel ( ) ; if ( articleLevel === level ) { return article . merge ( newArticle ) ; } else if ( level . indexOf ( articleLevel ) === 0 ) { const articles = editArticleInList ( article . getArticles ( ) , level , newArticle ) ; return article . set ( "articles" , articles ) ; } else { return article ; } } ) ; } param { Part } part param { string } level param { Article } newArticle return { Part } function editArticleInPart ( part , level , newArticle ) { let articles = part . getArticles ( ) ; articles = editArticleInList ( articles , level , newArticle ) ; return part . set ( "articles" , articles ) ; } param { Summary } summary param { string } level param { Article | Part } newValue return { Summary } function mergeAtLevel ( summary , level , newValue ) { const levelParts = level . split ( "." ) ; const partIndex = Number ( levelParts [ 0 ] ) - 1 ; let parts = summary . getParts ( ) ; let part = parts . get ( partIndex ) ; if ( ! part ) { return summary ; } const isEditingPart = levelParts . length < 2 ; if ( isEditingPart ) { part = part . merge ( newValue ) ; } else { part = editArticleInPart ( part , level , newValue ) ; } parts = parts . set ( partIndex , part ) ; return summary . set ( "parts" , parts ) ; } export default mergeAtLevel ;