yield IEnumerable

yield IEnumerable

Сообщение BenjaminMoore 23 июн 2014, 18:58

Тут небольшая фишка C#, достаточно полезная, если понимать, что происходит.
Вкратце, когда Вам нужен набор рандомных чисел, обычно все создают лист\массив и набивают его рандомными значениями, но можно поступить попроще.
Это подходит и не только для рандомных чисел, но и для последовательности значений вычисляемых по какой-то формуле.

Например, чтобы получить набор рандомных float, достаточно объявить такой метод
Синтаксис:
Используется csharp
    private IEnumerable<float> RangeFloat(float min, float max, int count)
    {
        for (var i = 0; i < count; i++)
            yield return Random.Range(min, max);
    }
 


и использовать его так

Синтаксис:
Используется csharp
    foreach (var f in RangeFloat(min: 0f, max: 10f, count: 10))
        print(f);
 


ниже пример с рандомными флоатами, рандомными векторами и числами фибоначи

Синтаксис:
Используется csharp
using System.Collections.Generic;
using UnityEngine;
using Func = System.Func<float, float, float>;

public class TestIEnumerable : MonoBehaviour
{
    private void Awake()
    {
        const int countFloat = 10, countFib = 10, countVector = 10;

        print("Float Random Range " + countFloat);
        foreach (var f in RangeFloat(min: 0f, max: 10f, count: countFloat))
        {
            print(f);
        }

        print("Fibonacci Range " + countFib);
        foreach (var f in RangeFibonacci(count: countFib))
        {
            print(f);
        }

        print("Vector3 Random Range " + countVector);
        foreach (var v in RangeVector3(min: Vector3.zero, max: Vector3.one * 10f, count: countVector))
        {
            var go = GameObject.CreatePrimitive(PrimitiveType.Cube);
            go.transform.position = v;
            print(v);
        }
    }

    private Func random = Random.Range;

    private IEnumerable<float> RangeFloat(float min, float max, int count)
    {
        for (var i = 0; i < count; i++)
            yield return random(min, max);
    }

    private IEnumerable<int> RangeFibonacci(short count)
    {
        for (short i = 1; i < count; i++)
            yield return Fibonacci.Calculate(i);
    }

    private IEnumerable<Vector3> RangeVector3(Vector3 min, Vector3 max, int count)
    {
        for (var i = 0; i < count; i++)
            yield return new Vector3(random(min.x, max.x), random(min.y, max.y), random(min.z, max.z));
    }


   
    private static class Fibonacci
    {
        private static readonly Matrix2 FibMtx = new Matrix2 { OneOne = 1, OneTwo = 1, TwoOne = 1 };
        private static readonly Matrix2 Identity = new Matrix2 { OneOne = 1, TwoTwo = 1 };

        private struct Matrix2
        {
            public int OneOne, OneTwo, TwoOne, TwoTwo;
            public static Matrix2 operator *(Matrix2 lhs, Matrix2 rhs)
            {
                return new Matrix2
                {
                    OneOne = lhs.OneOne * rhs.OneOne + lhs.OneTwo * rhs.TwoOne,
                    OneTwo = lhs.OneOne * rhs.OneTwo + lhs.OneTwo * rhs.TwoTwo,
                    TwoOne = lhs.TwoOne * rhs.OneOne + lhs.TwoTwo * rhs.TwoOne,
                    TwoTwo = lhs.TwoOne * rhs.OneTwo + lhs.TwoTwo * rhs.TwoTwo
                };
            }
        }

        private static Matrix2 MatrixPower(Matrix2 x, short power)
        {
            if (power == 0) return Identity;
            if (power == 1) return x;
            int n = 15;
            while ((power <<= 1) >= 0) n--;
            Matrix2 tmp = x;
            while (--n > 0)
                tmp = (tmp * tmp) * (((power <<= 1) < 0) ? x : Identity);
            return tmp;
        }

        public static int Calculate(short n)
        {
            return MatrixPower(FibMtx, (short)(n - 1)).OneOne;
        }
    }
}
 
My hands are hard. My mind is core.
ring0x0000 c0x0063 | write code in rust right now
Аватара пользователя
BenjaminMoore
UNITрон
 
Сообщения: 338
Зарегистрирован: 03 янв 2013, 18:07
Skype: benjminmoore

Вернуться в Tips & Tricks

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4