سؤال

وأريد أن تولد سلسلة مثل جدول الضرب. ذلك لبداية 1 وتوقف 10 أنا أبحث عن سلسلة مثل

1, 2, 3, 4, 5, 6, 7, 8, 9, 10,  // 1*1 - 1*10
2, 4, 6, 8, 10, 12, 14, 16, 18, 20, // 2*1 - 2*10
3, 6, 9, 12, ... // 3*1 - 3*10

وهنا هي لغتي بداية عرجاء في ذلك، ولكن أنا لا يمكن أن يبدو لمعرفة كيفية زيادة نظيفة ي عند الوصول إلى المحطة، أو كيفية إعادة ضبط ط العودة إلى البداية.

let multable (start,stop) =
    (start,start)
    |> Seq.unfold(
        fun (i,j) ->
        Some(i*j, (i+1, j)))

let its = multable(1, 1)

let first10 = Seq.take 10 its
printf "%A" (Seq.to_list first10)  

والتي بالطبع يعطيني 1، 2، 3، 4، 5، 6، 7، 8، 9، 10

هل كانت مفيدة؟

المحلول

استخدم تعبير تسلسل:

let multable start stop = seq{
    for a = start to stop do
      for b = start to stop do
        yield a*b
}

وإخراج:

> multable 1 3 |> Seq.to_list;;
val it : int list = [1; 2; 3; 2; 4; 6; 3; 6; 9]

وانها غريبة لتمثيل بنية 2D أساسي في هذا الشكل. لماذا لا سلسلة من متواليات:

let multable2 start stop = seq {
    for a = start to stop do yield seq {
      for b = start to stop do
        yield a*b
    }
}

وإخراج:

val multable2 : int -> int -> seq<seq<int>>

> multable2 1 3 |> Seq.to_list;;
val it : seq<int> list = [seq [1; 2; 3]; seq [2; 4; 6]; seq [3; 6; 9]]

إذا كنت تريد أن تكون "ذكية" وتجنب الضرب:

let multable4 start stop = seq {
    for a = start to stop do yield seq {
      let s = ref 0 in
      for b = start to stop do
        s:=!s+a
        yield !s
    }
}

وأنا لا أرى فعلا أي لطيفة الجاهزة "تسلسل من ألف إلى باء" خارج تعبيرات comprehensions / تسلسل، على الرغم من أن هناك من الواضح [a..b] (القائمة) و[| a..b |] (مجموعة) الذي يمكن أن المشروع من خلال Seq.unfold، Seq.map، وما إلى ذلك لجعل تسلسل.

نصائح أخرى

لا أستطيع أن أفكر حقا في كثير من الحالات حيث كنت تفضل Seq.unfold على قائمة الفهم يعادل:

> let multiplication n m = [for a in 1 .. n -> [for b in 1 .. m -> a * b ] ];;

val multiplication : int -> int -> int list list

> multiplication 5 5;;
val it : int list list =
  [[1; 2; 3; 4; 5]; [2; 4; 6; 8; 10]; [3; 6; 9; 12; 15]; [4; 8; 12; 16; 20];
   [5; 10; 15; 20; 25]]

وأحيانا أساليب Array.init هي مفيدة جدا:

> let multiplication n m = Array2D.init n m (fun n m -> n * m);;

val multiplication : int -> int -> int [,]

> multiplication 5 5;;
val it : int [,] = [[0; 0; 0; 0; 0]
                    [0; 1; 2; 3; 4]
                    [0; 2; 4; 6; 8]
                    [0; 3; 6; 9; 12]
                    [0; 4; 8; 12; 16]]
let Table r c =
    [for row in 1..r do
        yield [for col in 1..c do
                    yield row * col]]
printfn "%A" (Table 5 4)                    
// [[1; 2; 3; 4]; [2; 4; 6; 8]; [3; 6; 9; 12]; [4; 8; 12; 16]; [5; 10; 15; 20]]

إليك طريقة أخرى لاستخدام متواليات:

let rec fromXToY x y =
  seq {
    if x <= y
    then yield x; yield! fromXToY (x + 1) y;
    else ()
  }

let scaledSequence factor items =
  Seq.map (fun x -> factor * x) items

let mulTable x y =
  let sequenceOfIntegersMultipliedByValue = (fun n -> scaledSequence n (fromXToY x y))
  let seqOfSeqOfValues = Seq.map sequenceOfIntegersMultipliedByValue (fromXToY x y)
  // Convert the sequence of sequences to a simple sequence of values
  Seq.fold Seq.append Seq.empty seqOfSeqOfValues
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top