2008-11-17 34 views
3

,說25,將其轉換成持續時間文本,如「3周,4天」轉換日爲特定的天量人類可讀的持續時間文本

C#和F#的解決辦法都很大,如果F#變化提供了對C#的改進。

編輯:解決方案應該擴展過去幾周,包括月份和年份。包括幾個世紀的獎勵積分等等。額外的獎勵,如果它是有點可配置的,這意味着你可以告訴方法排除標準化周。

回答

1

這是一個遞歸解決方案。請注意,由於月份和年份的長度有所不同,因此只能根據給定日曆中的特定時間點衡量持續時間。但假設固定長度,這是一個簡單的解決方案:

let divmod n m = n/m, n % m  

let units = [ 
    ("Centuries", TimeSpan.TicksPerDay * 365L * 100L); 
    ("Years", TimeSpan.TicksPerDay * 365L); 
    ("Weeks", TimeSpan.TicksPerDay * 7L); 
    ("Days", TimeSpan.TicksPerDay) 
] 

let duration days = 
    let rec duration' ticks units acc = 
     match units with 
     | [] -> acc 
     | (u::us) -> 
      let (wholeUnits, ticksRemaining) = divmod ticks (snd u) 
      duration' ticksRemaining us (((fst u), wholeUnits) :: acc) 
    duration' (TimeSpan.FromDays(float days).Ticks) units [] 
5
String.Format("{0} Weeks, {1} days", days/7, days % 7); 
+0

也許可以添加一些基本邏輯。例如。如果天數小於6,可以將其計爲天數,如果不使用複數,則不加s(或用'(s)'代替s)。 – Brian 2008-11-17 20:47:55

0
public class UnitOfMeasure { 
     public UnitOfMeasure(string name, int value) { 
      Name = name; 
      Value = value; 
     } 

     public string Name { get; set; } 
     public int Value { get; set; } 

     public static UnitOfMeasure[] All = new UnitOfMeasure[] { 
      new UnitOfMeasure("Year", 356), 
      new UnitOfMeasure("Month", 30), 
      new UnitOfMeasure("Week", 7), 
      new UnitOfMeasure("Day", 1) 
     }; 

     public static string ConvertToDuration(int days) { 
      List<string> results = new List<string>(); 

      for (int i = 0; i < All.Length; i++) { 
       int count = days/All[i].Value; 

       if (count >= 1) { 
        results.Add((count + " " + All[i].Name) + (count == 1 ? string.Empty : "s")); 
        days -= count * All[i].Value; 
       } 
      } 

      return string.Join(", ", results.ToArray()); 
     } 
    } 
0

下面是基於此前發佈的C#版本的F#版本。主要區別在於它是適用性的而不是命令性的(沒有可變變量)。

#light 
let conversions = [| 
    365, "Year", "Years" 
    30, "Month", "Months" 
    7, "Week", "Weeks" 
    1, "Day", "Days" |] 
let ToDuration numDays = 
    conversions 
    |> Array.fold_left (fun (remainDays,results) (n,sing,plur) -> 
     let count = remainDays/n 
     if count >= 1 then 
      remainDays - (count * n), 
       (sprintf "%d %s" count (if count=1 then sing else plur)) :: results 
     else 
      remainDays, results 
    ) (numDays,[]) 
    |> snd |> (fun rs -> System.String.Join(", ", List.rev rs |> List.to_array)) 
printfn "%s" (ToDuration 1008)  
相關問題