2016-10-31 2 views
1

Ich habe mich vor kurzem in funktionale Programmierung verliebt und angefangen, ramda.js zu lernen, aber ich kann mich noch nicht in die funktionale Denkweise hineinversetzen. Ich habe 2 Arrays von Strings (sie sind tatsächlich geteilte Strings) und ich möchte herausfinden, wie viele Zeichen in der ersten Zeichenfolge gleich denen in der zweiten Zeichenfolge in der gleichen Position sind. imperativ würde ich entlang der Linien von etwas wirklich einfach tun:Vergleichen von 2 Arrays und Finden gleicher Werte mit Ramda

let counter = 0 
for(let i = 0; i < array.length; i++){ 
    if(firstArray[i] === secondArray[i]) counter++ 
} 

aber wie würde ich es tun mit Ramda?

Antwort

4

"... mit rambda"

Hier ein Art und Weise können Sie es tun - es gibt unzählige andere Möglichkeiten ...

const a = 
    'abcdefg' 

const b = 
    'abcxyzg' 

const countEqualChars = (a, b) => 
    R.sum(R.zipWith(R.equals, a, b)) 

countEqualChars(a,b) 
// 4 

Aber ...

Das ist im Grunde der falsche Weg für Sie, sich der funktionalen Programmierung zu nähern. Vergessen Sie Rambda, bis Sie ein gutes Gespür dafür haben, wie Sie Programme funktional begründen können. Sie werden die Bequemlichkeit von Rambda nie schätzen können, wenn Sie nicht wissen, wie die Dinge auf einer fundamentalen Ebene funktionieren.

Beginnen Sie mit dem Lernen über Rekursion als Alternative zu for/while Schleifen. Es ist nichts falsch mit Loops, aber Rekursion ermöglicht es Ihnen, die Dinge in eine schönere Art und Weise manchmal auszudrücken ...

const a = 
 
    'abcdefg' 
 

 
const b = 
 
    'abcxyzg' 
 

 
const countEqualChars = ([ x, ...xs ], [ y, ...ys ]) => 
 
{ 
 
    if (x === undefined || y === undefined) 
 
    return 0 
 
    else if (x === y) 
 
    return 1 + countEqualChars (xs, ys) 
 
    else 
 
    return countEqualChars (xs, ys) 
 
} 
 

 
console.log (countEqualChars (a, b)) 
 
// 4

Nun sehen wir, dass diese Funktion ziemlich viel tut. Wir untersuchen Felder Element für Element, führen Vergleiche und Zählen durch. Vielleicht könnten wir das in einzelne Aufgaben aufteilen, damit unsere Funktion im Laufe der Zeit etwas aufrechterhaltbar ist. Beginnen wir mit einer Funktion starten, die uns gleich Indizes von zwei Arrays ...

const zip = ([ x, ...xs ], [ y, ...ys ]) => 
 
    x === undefined && y === undefined 
 
    ? [] 
 
    : [ [ x, y ] ] .concat (zip (xs, ys)) 
 

 
console.log (zip ([ 1, 2, 3 ], [ 'a', 'b', 'c' ])) 
 
// [ [ 1, 'a' ] 
 
// , [ 2, 'b' ] 
 
// , [ 3, 'c' ] 
 
// ]

Neben paaren können, wir die eingebaute in filter Funktion verwenden können, um ein neues Array nur herzustellen, die das, was wir wollen

const xs = 
 
    [ 1, 1, 2, 2, 3, 3, 4, 4 ] 
 

 
const justThrees = 
 
    xs.filter (x => x === 3) 
 

 
console.log (justThrees) 
 
// [ 3, 3 ]

jene zip und filter Strats kombinieren, können wir jeden Index von den Saiten paaren, dann die Paare entfernen, die ...

const zip = ([ x, ...xs ], [ y, ...ys ]) => 
 
    x === undefined && y === undefined 
 
    ? [] 
 
    : [ [ x, y ] ] .concat (zip (xs, ys)) 
 
} 
 

 
const eq = (x, y) => 
 
    x === y 
 

 
const apply = f => xs => 
 
    f (...xs) 
 

 
const a = 
 
    'abcdefg' 
 

 
const b = 
 
    'abcxyzgh' 
 

 
const matches = 
 
    zip (a, b) .filter (apply (eq)) 
 

 
console.log (matches) 
 
// [ [ 'a', 'a' ] 
 
// , [ 'b', 'b' ] 
 
// , [ 'c', 'c' ] 
 
// , [ 'g', 'g' ] 
 
// ]

jetzt nicht zusammenpassen alles, was übrig bleibt ist das Zählen die passenden Paare.Wir werden das Ganze in eine Funktion machen, so dass Sie es wiederverwenden als

benötigt

const zip = ([ x, ...xs ], [ y, ...ys ]) => 
 
    x === undefined && y === undefined 
 
    ? [] 
 
    : [ [ x, y ] ] .concat (zip (xs, ys)) 
 

 
const eq = (x, y) => 
 
    x === y 
 

 
const apply = f => xs => 
 
    f (...xs) 
 

 
const countEqualChars = (a, b) => 
 
    zip (a, b) 
 
    .filter (apply (eq)) 
 
    .length 
 

 
console.log (countEqualChars ('abcdefg', 'abcxyzgh')) 
 
// 4

vor allem ...

Sie werden sehen, dass Die von uns abgeleitete Lösung ist leicht verschieden als die, die wir mit Rambda verwendet haben. Das liegt daran, dass das Programmieren keine Magie ist und Sie werden eine Menge Ihrer eigenen Werkzeuge erfinden, bevor Sie erkennen, welche anderen Werkzeuge überhaupt existieren oder verstehen, was sie tun.

Es gibt Hunderte von Möglichkeiten, um das Problem zu lösen, das ich gerade getan habe, und es gibt Kompromisse, die ich bei jeder meiner Entscheidungen berücksichtigt habe. Ihr ganzes Ziel ist es, Ihr Programm in seine Bestandteile zu zerlegen und die Kompromisse im Laufe der Zeit zu lernen.

Vergleichen Sie das mit dem Versuch, zu verstehen, warum eine Funktion in einer Bibliothek existiert, nur damit Sie raten können, wo Sie sie verwenden können ... Sie werden gut in der funktionalen Programmierung, indem Sie die clevere Rambda-Datei kopieren und einfügen -Linien. Sobald Sie verstehen warumequals, zipWith und sum existieren, werden Sie wissen, wann Sie sie verwenden.

Lassen Sie mich wissen, wenn ich etwas anderes^klären helfen _^

+1

ich nicht für eine vollständigere eine bessere Gedanken Antwort gewünscht hätte. Vielen Dank ^^. –

1

Ich kann nicht mit der anderen, ausgezeichneten Antwort konkurrieren, aber vergessen Sie nicht der array Prototyp viele nützlichen Methoden wie filter hat oder reduce!

var countMatches = (a, b) => a.reduce((sum, c, i) => 
 
    b[i] === c 
 
    ? ++sum 
 
    : sum 
 
, 0); 
 

 
var set1 = "1234678".split(""); 
 
var set2 = "1234568".split(""); 
 
console.log(countMatches(set1, set2));

+0

nette praktische Anwendung von 'reduce' - mein einziger Rat wäre,' sum + 1' anstelle von 'sum ++' zurückzugeben, da Zahlen sowieso schon unveränderlich sind. – naomik

+0

Ich dachte nicht daran, es so zu benutzen. Ich benutze die standard map/reduce/filter array Methoden für eine ganze Weile, aber die meiste Zeit werden die Funktionen sehr groß und ich mag es nicht die Indizes in der params Liste zu benutzen. Gute Lösung –

Verwandte Themen