Πώς να απλοποιήσετε τη βάση κώδικα με χάρτη (), μείωση () και φίλτρο () σε JavaScript

Όταν διαβάζετε για το Array.reduce και πόσο δροσερό είναι, το πρώτο και μερικές φορές το μόνο παράδειγμα που βρίσκετε είναι το άθροισμα των αριθμών. Αυτός δεν είναι ο ορισμός μας για «χρήσιμο». ;

Επιπλέον, δεν το έχω δει ποτέ σε πραγματική βάση κώδικα. Όμως, αυτό που έχω δει πολλά είναι οι φράσεις 7-8 γραμμής για βρόχο για την επίλυση μιας κανονικής εργασίας, όπου το Array.reduce θα μπορούσε να το κάνει σε μία γραμμή.

Πρόσφατα ξαναγράψαμε μερικές ενότητες χρησιμοποιώντας αυτές τις υπέροχες λειτουργίες. Με εξέπληξε πόσο απλοποιήθηκε η βάση κώδικα. Λοιπόν, παρακάτω είναι μια λίστα με καλούδια.

Εάν έχετε ένα καλό παράδειγμα χρήσης χάρτη ή μεθόδου μείωσης - δημοσιεύστε τον στην ενότητα σχολίων. ;

Ας αρχίσουμε!

1. Αφαιρέστε τα διπλά από μια σειρά αριθμών / συμβολοσειρών

Λοιπόν, αυτό είναι το μόνο που δεν αφορά το χάρτη / μείωση / φίλτρο , αλλά είναι τόσο συμπαγές που ήταν δύσκολο να μην το βάλετε στη λίστα. Επιπλέον, θα το χρησιμοποιήσουμε και σε μερικά παραδείγματα.

const values = [3, 1, 3, 5, 2, 4, 4, 4]; const uniqueValues = [...new Set(values)]; // uniqueValues is [3, 1, 5, 2, 4]

2. Μια απλή αναζήτηση (με διάκριση πεζών-κεφαλαίων)

Η μέθοδος φίλτρου () δημιουργεί έναν νέο πίνακα με όλα τα στοιχεία που περνούν τη δοκιμή που πραγματοποιείται από την παρεχόμενη συνάρτηση.

const users = [ { id: 11, name: 'Adam', age: 23, group: 'editor' }, { id: 47, name: 'John', age: 28, group: 'admin' }, { id: 85, name: 'William', age: 34, group: 'editor' }, { id: 97, name: 'Oliver', age: 28, group: 'admin' } ]; let res = users.filter(it => it.name.includes('oli')); // res is []

3. Μια απλή αναζήτηση (χωρίς διάκριση πεζών-κεφαλαίων)

let res = users.filter(it => new RegExp('oli', "i").test(it.name)); // res is [ { id: 97, name: 'Oliver', age: 28, group: 'admin' } ]

4. Ελέγξτε εάν κάποιος από τους χρήστες έχει δικαιώματα διαχειριστή

Η μέθοδος μερικών () ελέγχει εάν τουλάχιστον ένα στοιχείο στη συστοιχία περνά τη δοκιμή που πραγματοποιείται από την παρεχόμενη συνάρτηση.

const hasAdmin = users.some(user => user.group === 'admin'); // hasAdmin is true

5. Ισιώνοντας μια σειρά συστοιχιών

Το αποτέλεσμα της πρώτης επανάληψης ισούται με: [… [],… [1, 2, 3]] σημαίνει ότι μετατρέπεται σε [1, 2, 3] - αυτή η τιμή που παρέχουμε ως «acc» στη δεύτερη επανάληψη και σύντομα.

const nested = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; let flat = nested.reduce((acc, it) => [...acc, ...it], []); // flat is [1, 2, 3, 4, 5, 6, 7, 8, 9]

Μπορούμε να βελτιώσουμε ελαφρώς αυτόν τον κώδικα παραλείποντας έναν κενό πίνακα []ως το δεύτερο όρισμα για μείωση (). Στη συνέχεια, η πρώτη τιμή του ένθετου θα χρησιμοποιηθεί ως η αρχική τιμή acc . Χάρη στον Vladimir Efanov.

let flat = nested.reduce((acc, it) => [...acc, ...it]); // flat is [1, 2, 3, 4, 5, 6, 7, 8, 9]

Σημειώστε ότι η χρήση του χειριστή spread μέσα σε μια μείωση δεν είναι μεγάλη για απόδοση. Αυτό το παράδειγμα ισχύει όταν η μέτρηση της απόδοσης έχει νόημα για τη θήκη χρήσης σας. ☝️

Χάρη στον Paweł Wolak, εδώ είναι ένας πιο σύντομος τρόπος χωρίς το Array. Μείωση:

let flat = [].concat.apply([], nested);

Επίσης, το Array.flat έρχεται, αλλά εξακολουθεί να είναι ένα πειραματικό χαρακτηριστικό.

6. Δημιουργήστε ένα αντικείμενο που περιέχει τη συχνότητα του καθορισμένου κλειδιού

Ας ομαδοποιήσουμε και μετρήσουμε την ιδιότητα «ηλικία» για κάθε στοιχείο του πίνακα:

const users = [ { id: 11, name: 'Adam', age: 23, group: 'editor' }, { id: 47, name: 'John', age: 28, group: 'admin' }, { id: 85, name: 'William', age: 34, group: 'editor' }, { id: 97, name: 'Oliver', age: 28, group: 'admin' } ]; const groupByAge = users.reduce((acc, it) => , {}); // groupByAge is {23: 1, 28: 2, 34: 1}

Ευχαριστώ τον sai krishna που πρότεινε αυτό!

7. Ευρετηρίαση ενός πίνακα αντικειμένων (πίνακας αναζήτησης)

Αντί να επεξεργαζόμαστε ολόκληρο τον πίνακα για την εύρεση ενός χρήστη με αναγνωριστικό, μπορούμε να κατασκευάσουμε ένα αντικείμενο όπου το αναγνωριστικό του χρήστη αντιπροσωπεύει ένα κλειδί (με συνεχή χρόνο αναζήτησης).

const uTable = users.reduce((acc, it) => (acc[it.id] = it, acc), {}) // uTable equals: { 11: { id: 11, name: 'Adam', age: 23, group: 'editor' }, 47: { id: 47, name: 'John', age: 28, group: 'admin' }, 85: { id: 85, name: 'William', age: 34, group: 'editor' }, 97: { id: 97, name: 'Oliver', age: 28, group: 'admin' } }

Είναι χρήσιμο όταν πρέπει να έχετε πρόσβαση στα δεδομένα σας με αναγνωριστικό όπως uTable[85].nameπολλά.

8. Εξαγάγετε τις μοναδικές τιμές για το δεδομένο κλειδί κάθε στοιχείου του πίνακα

Ας δημιουργήσουμε μια λίστα με υπάρχουσες ομάδες χρηστών. Η μέθοδος map () δημιουργεί έναν νέο πίνακα με τα αποτελέσματα της κλήσης μιας παρεχόμενης συνάρτησης σε κάθε στοιχείο του πίνακα κλήσεων.

const listOfUserGroups = [...new Set(users.map(it => it.group))]; // listOfUserGroups is ['editor', 'admin'];

9. Αντιστροφή χάρτη-τιμής αντικειμένου

const cities = { Lyon: 'France', Berlin: 'Germany', Paris: 'France' }; let countries = Object.keys(cities).reduce( (acc, k) => (acc[cities[k]] = [...(acc[cities[k]] || []), k], acc) , {}); // countries is { France: ["Lyon", "Paris"], Germany: ["Berlin"] }

Αυτή η επένδυση μοιάζει αρκετά δύσκολη. Χρησιμοποιούμε τον τελεστή κόμμα εδώ και αυτό σημαίνει ότι επιστρέφουμε την τελευταία τιμή σε παρένθεση - acc. Ας ξαναγράψουμε αυτό το παράδειγμα με έναν τρόπο πιο έτοιμο για παραγωγή και απόδοση:

let countries = Object.keys(cities).reduce((acc, k) =>  []; acc[country].push(k); return acc; , {});

Εδώ δεν χρησιμοποιούμε spread operator - δημιουργεί μια νέα συστοιχία σε κάθε κλήση μείωσης () , η οποία οδηγεί σε μεγάλη ποινή απόδοσης: O (n²). Αντίθετα, η παλιά καλή μέθοδος push () .

10. Δημιουργήστε έναν πίνακα τιμών Fahrenheit από έναν πίνακα τιμών Κελσίου

Σκεφτείτε το ως επεξεργασία κάθε στοιχείου με έναν δεδομένο τύπο;

const celsius = [-15, -5, 0, 10, 16, 20, 24, 32] const fahrenheit = celsius.map(t => t * 1.8 + 32); // fahrenheit is [5, 23, 32, 50, 60.8, 68, 75.2, 89.6]

11. Κωδικοποιήστε ένα αντικείμενο σε μια συμβολοσειρά ερωτήματος

const params = {lat: 45, lng: 6, alt: 1000}; const queryString = Object.entries(params).map(p => encodeURIComponent(p[0]) + '=' + encodeURIComponent(p[1])).join('&') // queryString is "lat=45&lng=6&alt=1000"

12. Εκτυπώστε έναν πίνακα χρηστών ως αναγνώσιμη συμβολοσειρά μόνο με καθορισμένα πλήκτρα

Μερικές φορές θέλετε να εκτυπώσετε τη σειρά αντικειμένων σας με επιλεγμένα πλήκτρα ως συμβολοσειρά, αλλά συνειδητοποιείτε ότι το JSON.stringify δεν είναι τόσο καλό;

const users = [ { id: 11, name: 'Adam', age: 23, group: 'editor' }, { id: 47, name: 'John', age: 28, group: 'admin' }, { id: 85, name: 'William', age: 34, group: 'editor' }, { id: 97, name: 'Oliver', age: 28, group: 'admin' } ]; users.map(({id, age, group}) => `\n${id} ${age} ${group}`).join('') // it returns: " 11 23 editor 47 28 admin 85 34 editor 97 28 admin"

Το JSON.stringify μπορεί να κάνει την έξοδο συμβολοσειράς πιο ευανάγνωστη, αλλά όχι ως πίνακα:

JSON.stringify(users, ['id', 'name', 'group'], 2); // it returns: "[ { "id": 11, "name": "Adam", "group": "editor" }, { "id": 47, "name": "John", "group": "admin" }, { "id": 85, "name": "William", "group": "editor" }, { "id": 97, "name": "Oliver", "group": "admin" } ]"

13. Βρείτε και αντικαταστήστε ένα ζεύγος τιμών-κλειδιών σε μια σειρά αντικειμένων

Ας πούμε ότι θέλουμε να αλλάξουμε την ηλικία του John. Εάν γνωρίζετε τον δείκτη, μπορείτε να γράψετε αυτή τη γραμμή: users[1].age = 29. Ωστόσο, ας ρίξουμε μια ματιά σε έναν άλλο τρόπο να το κάνουμε:

const updatedUsers = users.map( p => p.id !== 47 ? p : {...p, age: p.age + 1} ); // John is turning 29 now

Εδώ αντί να αλλάξουμε το μεμονωμένο στοιχείο στη σειρά μας, δημιουργούμε ένα νέο με διαφορετικό μόνο ένα στοιχείο. Τώρα μπορούμε να συγκρίνουμε τις συστοιχίες μας μόνο με αναφορά, όπως updatedUsers == usersείναι εξαιρετικά γρήγορη! Το React.js χρησιμοποιεί αυτήν την προσέγγιση για να επιταχύνει τη διαδικασία συμφιλίωσης. Εδώ είναι μια εξήγηση.

14. Ένωση (A ∪ B) συστοιχιών

Less code than importing and calling the lodash method union.

const arrA = [1, 4, 3, 2]; const arrB = [5, 2, 6, 7, 1]; [...new Set([...arrA, ...arrB])]; // returns [1, 4, 3, 2, 5, 6, 7]

15. Intersection (A ∩ B) of arrays

The last one!

const arrA = [1, 4, 3, 2]; const arrB = [5, 2, 6, 7, 1]; arrA.filter(it => arrB.includes(it)); // returns [1, 2]

As an exercise try to implement difference (A \ B) of the arrays. Hint: use an exclamation mark.

Thanks to Asmor and incarnatethegreat for their comments about #9.

That’s it!

If you have any questions or feedback, let me know in the comments down below or ping me on Twitter.

If this was useful, please click the clap ? button down below a few times to show your support! ⬇⬇ ??

Here are more articles I’ve written:

How to get started with internationalization in JavaScript

By adapting our app for different languages and countries, we provide a better user experience. It’s simpler for users…

Production ready Node.js REST APIs Setup using TypeScript, PostgreSQL and Redis.

Πριν από ένα μήνα μου δόθηκε μια εργασία να δημιουργήσω ένα απλό API αναζήτησης. Το μόνο που έπρεπε να κάνει είναι να πάρει μερικά δεδομένα από τρίτους…

Ευχαριστούμε που διαβάσατε ❤️