Home > Enterprise >  A nested 'for' loop that returns each day of the month
A nested 'for' loop that returns each day of the month

Time:10-26

I want:

[1] "January has 31 days"
[1] "February has 29 days"
[1] "March has 31 days"
[1] "April has 30 days"
[1] "May has 31 days"
[1] "June has 30 days"
[1] "July has 31 days"
[1] "August has 31 days"
[1] "September has 30 days"
[1] "October has 31 days"
[1] "November has 30 days"
[1] "December has 31 days"

So far I have tried:

days <- c("31","29","31","30","31","30","31","31","30","31","30","31")
months <- c("January", "Februari", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")

for (i in days){
  for (j in months){
      cat(j, "has", i, "days\n")
   }    
}

The loop I created returns each j and i 12*12 times which is not correct.

CodePudding user response:

What you are looking for is:

days <- c("31","29","31","30","31","30","31","31","30","31","30","31")
months <- c("January", "Februari", "March", "April", "May", "June", "July", "September", "October", "November", "December")

for (i in seq_along(days)){ # seq works but as commented seq_along is the better option

    cat(months[i], "has", days[i], "days\n")

  }

also: you are missing august in your months vector

PS

as inspired by @U12-Forward this works as well:

invisible(sapply(1:12, function(x) cat(month.name[x], "has", days[x], "days\n")))

CodePudding user response:

I prefer mapply:

> invisible(mapply(function(i, j) cat(j, "has", i, "days\n"), days, months))
January has 31 days
Februari has 29 days
March has 31 days
April has 30 days
May has 31 days
June has 30 days
July has 31 days
August has 31 days
September has 30 days
October has 31 days
November has 30 days
December has 31 days
> 

Note: Added invisible so actual result of mapply isn't printed.


mapply iterates through multiple vectors in parallel.

CodePudding user response:

stringr::str_glue() provides a nice alternative. It's vectorised.

library("stringr")

days <- c("31", "29", "31", "30", "31", "30", "31", "31", "30", "31", "30", "31")
months <- c("January", "February", "March", "April", "May", "June", "July","August", "September", "October", "November", "December")

str_glue("{months} has {days} days")
#> January has 31 days
#> February has 29 days
#> March has 31 days
#> April has 30 days
#> May has 31 days
#> June has 30 days
#> July has 31 days
#> August has 31 days
#> September has 30 days
#> October has 31 days
#> November has 30 days
#> December has 31 days

Created on 2021-10-26 by the reprex package (v2.0.1)

CodePudding user response:

This is a vectorised operation, so you could do this without loops or apply statements.

sprintf('%s has %s days', months, days)

# [1] "January has 31 days"   "Februari has 29 days"  "March has 31 days"
# [4] "April has 30 days"     "May has 31 days"       "June has 30 days"
# [7] "July has 31 days"      "August has 31 days"    "September has 30 days"
#[10] "October has 31 days"   "November has 30 days"  "December has 31 days"

For display purposes, if you want every statement on new line -

cat(paste0(sprintf('%s has %s days', months, days), collapse = '\n'))

#January has 31 days
#Februari has 29 days
#March has 31 days
#April has 30 days
#May has 31 days
#June has 30 days
#July has 31 days
#August has 31 days
#September has 30 days
#October has 31 days
#November has 30 days
#December has 31 days
  • Related