Seks Ruby array-metoder, du har brug for at kende

Arrays er en af ​​de grundlæggende strukturer for programmering. At være i stand til hurtigt at manipulere og læse data ud af dem er afgørende for succes med at opbygge ting med computere. Her er seks metoder, du ikke kan undvære.

Kort / hver

Disse to metoder er meget ens. De giver dig mulighed for at gå gennem "hvert" element i en matrix og gøre noget ved det.

Tjek nogle kode:

array = [1, 2, 3] effects = array.each # create record from x  added = array.map x + 2 

Hvis vi læser fra added, får vi det [3, 4, 5]. Hvis vi læser fra effects, får vi det stadig [1, 2, 3]. Her er forskellen mellem disse to: .mapreturnerer et nyt modificeret array, hvorimod .eachdet originale array returneres.

Bivirkninger på kortet

Hvis du er vant til funktionel programmering, kan Ruby's .mapmåske virke meget mærkelig. Se på dette eksempel. Jeg har en enkel Eventklasse i mit projekt:

# we create an array of records 2.3.0 :025 > array = [e, e2, e3] => [#, #, #] # so far so good 2.3.0 :026 > new_array = array.map => [#, #, #] # uh-oh, that ain't right 2.3.0 :027 > array => [#, #, #]

Vi kan forvente, at vi arbejder med en slags kopi af vores poster i arrayet, men det er vi ikke. Det er alt sammen bare for at sige: vær forsigtig. Du kan nemt oprette bivirkninger i dine .mapfunktioner.

Ok let, det var det hårde. Glat sejlads herfra og ud.

Vælg

.selectgiver dig mulighed for at "finde" et element i en matrix. Du er nødt til at give .selecten funktion, der returnerer sand eller falsk, så den ved, om et array-element skal "beholde" eller ej.

2.3.0 :028 > array = ['hello', 'hi', 'goodbye'] 2.3.0 :029 > array.selectword => ["hello", "goodbye"]

Et lidt mere komplekst eksempel, sandsynligvis tættere på, hvordan du rent faktisk ville bruge dette. Lad os smide i .mapslutningen for godt mål:

2.3.0 :030 > valid_colors = ['red', 'green', 'blue'] 2.3.0 :031 > cars = [{type: 'porsche', color: 'red'}, {type: 'mustang', color: 'orange'}, {type: 'prius', color: 'blue'}] 2.3.0 :032 > cars.select valid_colors.include?(car[:color]) .map  => ["porsche", "prius"]

Ja, folkens, du kan slutte dig til disse metoder for at udøve ufattelig magt. Ok, du kan sikkert forestille dig det, men det er stadig sejt.

Endnu renere syntaks: .map (&: metode)

Hvis vi havde arbejdet med bilgenstande og ikke kun en simpel hash, kunne vi have brugt en renere syntaks. Jeg bruger et andet eksempel for kortfattethed. Måske forbereder vi denne liste over biler, der skal sendes i en API og har brug for at generere JSON. Vi kan bruge .to_jsonmetoden:

# using regular map syntax 2.3.0 :047 > cars.select .map car.to_json => ["{\"type\":\"porsche\",\"color\":\"red\"}", "{\"type\":\"prius\",\"color\":\"blue\"}"] # using the cleaner syntax 2.3.0 :046 > cars.selectcar.map(&:to_json) => ["{\"type\":\"porsche\",\"color\":\"red\"}", "{\"type\":\"prius\",\"color\":\"blue\"}"]

Afvise

Afvis er yin til .selectyang:

2.3.0 :048 > cars.reject valid_colors.include?(car[:color]) .mapcar => ["mustang"]

I stedet for at vælge de matrixelementer, vi ønsker, afviser vi alt, hvad der ikke gør vores funktion til at blive sand. Husk, at funktionen inde i vores afvisning er det, der bestemmer, om array-elementet returneres eller ej - hvis det er sandt, returneres varen, ellers ikke.

Reducere

Reducer har en mere kompleks struktur end vores andre matrixmetoder, men det bruges generelt til temmelig enkle ting i Ruby - for det meste matematiske ting. Vi tager et array og kører derefter en funktion på hvert element i det array. Denne gang bekymrer vi os om, hvad der returneres fra de andre matrixartikler . Typisk tilføjer vi en masse tal:

2.3.0 :049 > array = [1, 2, 3] 2.3.0 :050 > array.reduce => 6

Bemærk, at vi kan arbejde med strenge på samme måde:

2.3.0 :053 > array = ['amber', 'scott', 'erica'] 2.3.0 :054 > array.reduce sum + name => "amberscotterica"

Dette kan være nyttigt, hvis vi ser på en masse arbejdsoptegnelser. Hvis vi har brug for at tilføje samlede arbejdstimer, eller hvis vi vil finde ud af summen af ​​alle donationer sidste måned. En sidste note om .reduce. Hvis du arbejder med andet end almindelige gamle tal (eller strenge), skal du medtage en startværdi som argument:

array = [{weekday: 'Monday', pay: 123}, {weekday: 'Tuedsay', pay: 244}] array.reduce(0)  => 367 array.reduce(100) sum, day => 467

Der er selvfølgelig mere avancerede måder at bruge, .reducemen det er masser for at komme i gang.

Tilslutte

Jeg kaster ind .joinsom en bonus, fordi den er så nyttig. Lad os bruge vores biler igen:

2.3.0 :061 > cars.map car[:type].join(', ') => "porsche, mustang, prius"

.joinligner meget .reducebortset fra at den har en superren syntaks. Det tager et argument: en streng, der indsættes mellem alle matrixelementer. .joinopretter en lang streng ud af hvad du giver den, selvom din matrix er en flok ting, der ikke er streng:

2.3.0 :062 > cars.join(', ') => "{:type=>\"porsche\", :color=>\"red\"}, {:type=>\"mustang\", :color=>\"orange\"}, {:type=>\"prius\", :color=>\"blue\"}" 2.3.0 :065 > events.join(', ') => "#, #, #"

Hvorfor ikke bare smide det hele sammen

Lad os bruge alle matrixmetoderne i dette indlæg sammen! Ti dages opgaver, og det er tilfældigt, hvor lang tid hver tager. Vi vil vide den samlede tid, vi bruger på husarbejde. Dette forudsættes, at vi slap af og ignorerer alt, der tager længere tid end 15 minutter. Eller udsæt indtil en anden dag alt, hvad der kan gøres på mindre end 5:

days = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] days.map{|day| day.odd? ? {task: 'dishes', minutes: Random.rand(20)} : {task: 'sweep', minutes: Random.rand(20)}} .select .rejecttask .reduce(0)  sum + task[:minutes]

Mit svar er irrelevant, fordi du får forskellige tilfældige minutter for dine opgaver at tage. Hvis noget af dette er nyt eller forvirrende, skal du skyde en Ruby-konsol op og give den en hvirvel.

PS: Denne ? :forretning .mapkaldes en ternary. Det er bare en if-else-erklæring. Jeg bruger det kun her for at være fancy og få alt på "en" linje. Du bør undgå en så kompliceret ternær i din egen kodebase.

Vi ses næste gang!