Conversione funzionale JavaScript dalla lista semplice all'albero

3

Ho seguito i tutorial di RxJS link . Quasi tutti gli esercizi prevedono il passaggio da una struttura gerarchica a una struttura piatta, quindi ho pensato di provare a fare il contrario.

Voglio convertire da una matrice piatta a una struttura ad albero basata su una proprietà di ciascun elemento dell'array, utilizzando gli stessi costrutti funzionali del tutorial.

vale a dire. Vai da questo:

var videos = [
    {
        "id": 70111470,
        "title": "Die Hard",
        "category": "Action"
    },
    {
        "id": 654356453,
        "title": "Bad Boys",
        "category": "Action"
    },
    {
        "id": 65432445,
        "title": "Anchorman",
        "category": "Comedy"
    },
    {
        "id": 675465,
        "title": "Everest",
        "category": "New Release"
    }
];

A questo (in base alla categoria di ciascun video):

result === [
    {
        "category": "Action",
        "videos": [
            {
                "id": 70111470,
                "title": "Die Hard"
            },
            {
                "id": 654356453,
                "title": "Bad Boys"
            }
        ]
    },
    {
        "category": "Comedy",
        "videos": [
            {
                "id": 65432445,
                "title": "Anchorman"
            }
        ]
    },
    {
        "category": "New Release",
        "videos": [
            {
                "id": 675465,
                "title": "Everest"
            }
        ]
    }
];

Ho trovato il seguente codice che funziona, ma mi sento come se mi mancasse un modo più semplice (magari risolvendo in una singola riduzione) che a sua volta sarebbe più performante (piuttosto che filtrare i video molte volte):

var result = 
    videos.reduce(function(catArray, video) {
       var catName = video.category;
       if (catArray.indexOf(catName) === -1) {
          catArray.push(catName);
       }
       return catArray;
    }, [])
    .map(function(categoryName) {
        return {
            category: categoryName,
            videos: videos.filter(function(video) {
                        return video.category === categoryName;
                    }).map(function(video) {
                        return {
                            id: video.id,
                            title: video.title
                        };
                    })
        };
    });

C'è un modo migliore di utilizzare i metodi funzionali?

    
posta Glenn Allen 14.01.2016 - 07:47
fonte

1 risposta

3

Questo è più semplice di un albero perché il risultato può avere solo un livello. Tutto ciò che si desidera è raggruppare la matrice per categoria e quindi mappare ciascun gruppo in oggetti. La parte della mappa sarà semplicemente riorganizzare le cose un po 'nella tua struttura finale desiderata. Non dovrai filtrare l'elenco completo di videos all'interno della mappa come fai attualmente.

Sfortunatamente, JavaScript non è particolarmente amichevole per il paradigma funzionale per impostazione predefinita, quindi non ha un groupBy incorporato. Quindi puoi reimplementare il raggruppamento all'interno del tuo riduci oppure puoi usarne uno da una libreria esterna come Ramda . Il codice di esempio dovrebbe aiutarti a capire come funziona groupBy .

    
risposta data 14.01.2016 - 11:43
fonte

Leggi altre domande sui tag