2016-03-20 8 views
1

Ich versuche Index aller Instanzen zu finden, sagen wir Header und Footer in einem Array.Wie findet man den Index aller Vorkommen eines Elements im Array (Ramda.js-Weg)?

var arr = [ 
'data', 
'data', 
'data', 
'data', 
'Header', 
'data', 
'data', 
'data', 
'Footer', 
'data', 
'Header', 
'data', 
'Footer', 
'data' 
]; 

Ich weiß, wie dies im Klar JS tun (How to find index of all occurrences of element in array?), aber ich frage mich, wie es in FP, ramda.js insbesondere geschehen würde?

Ich weiß, wie dies für die erste Instanz R.findIndex(R.test(_regexForHeader)) zu tun, kann aber nicht meinen Kopf umschlingen durch alle Array. Danke für die Hilfe.

Antwort

3

@ pierrebeitz 'Antwort ist on-Punkt, nämlich, wenn Sie Zugriff auf Indizes benötigen, während Sie über eine Liste iterieren, werden Sie normalerweise die Liste zusammen mit ihren Indizes zippen. Ramda bietet eine R.addIndex Funktion zum Ändern von Funktionen wie map, um den Index zusammen mit jedem Element während der Iteration bereitzustellen.

Die Verschachtelung in seinem Beispiel auch mit einer Zusammensetzung Pipeline ersetzt werden kann, wenn Sie es vorziehen:

const zipWithIndex = addIndex(map)(pair); 

const isHeaderOrFooter = either(equals('Header'), equals('Footer')); 

const hfIndices = pipe(
    zipWithIndex, 
    filter(pipe(head, isHeaderOrFooter)), 
    map(nth(1)) 
); 

hfIndices(arr); 

Eines der mit diesen beiden Ansätzen aufmerksam sein wird Sie über die Liste mehrere Iterieren am Ende dann mal. Dies ist normalerweise kein Problem für eine kleine Liste, aber für größere Listen sollten Sie vielleicht R.into in Erwägung ziehen, die die Karten effektiv verschmilzt und zu einem Wandler zusammenfasst, der jetzt nur einen einzigen Durchlauf über die Liste durchführt (siehe http://simplectic.com/blog/2015/ramda-transducers-logs/ für ein gutes Intro für Wandler).

Dies kann durch Vertauschen die Zusammensetzung aus pipe zu compose (Transducer Funktionen zusammensetzen in der umgekehrten Reihenfolge) und Umwickeln mit into mit einem kleinen zwicken hfIndices in dem obigen Beispiel erzielt werden.

const hfIndices = into([], compose(
    zipWithIndex, 
    filter(pipe(head, isHeaderOrFooter)), 
    map(nth(1)) 
)); 
0

Ich bin nicht so in FP, aber ich glaube, dass Sie die Daten "generieren" müssen, mit denen Sie arbeiten möchten. Sie müssen einen Index hinzufügen, um danach Ihre Filter anwenden:

var arr = ['data', 'data', 'data', 'data', 'Header', 'data', 'data', 'data', 'Footer', 'data', 'Header', 'data', 'Footer', 'data']; 

R.map((e) => e[1], 
    R.filter(val => val[0] == 'Header' || val[0] == 'Footer', 
    R.addIndex(R.map)((e, i) => [e,i], arr) 
) 
); 
// => [4, 8, 10, 12] 

Dies ist nicht die aufwendigste Lösung, aber es sollten Sie loslegen!

Verwandte Themen