Chinar blog :www.chinar.xin
Chinar 坚持将简单的生活方式,带给世人! (拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) |
助力查询学习 LinQ 查询语句的具体用法、可用于备忘 为新手节省宝贵的时间,避免采坑! |
Chinar 教程效果:暂时留空
Where —— 使满足条件的数据通过,排除被限制的元素
查询狗狗数据中,重量大于 30 的狗
// ========================================================
// 描述:Where 筛选满足/限制条件
// 作者:Chinar
// 创建时间:2019-01-03 23:55:27
// 版 本:1.0
// ========================================================
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace ChinarDemo.LinQ
{
public class Chinar_Where : MonoBehaviour
{
void Start()
{
//一个数据列表,并添加数据
List<Dog> dogs = new List<Dog>()
{
new Dog("金毛", 2000, 62),
new Dog("二哈", 1500, 45),
new Dog("泰迪", 1000, 15),
new Dog("吉娃娃", 500, 10)
};
//1-查询 狗狗中 重量大于30
dogs.Where(dog => dog.Weight > 30).ToList().ForEach(dog => print(dog.ToString()));
//2-LinQ 查询 狗狗中 重量大于30
(from dog in dogs where dog.Weight > 30 select dog).ToList().ForEach(dog => print(dog.ToString()));
}
}
}
打印输出:
Name: 金毛, Price: 2000, Weight: 62
Name: 二哈, Price: 1500, Weight: 45
Name: 金毛, Price: 2000, Weight: 62
Name: 二哈, Price: 1500, Weight: 45
数据类 —— 为了简化代码,将该类放于 ChinarDemo.LinQ
命名空间中。便于以下例子使用此数据!
namespace ChinarDemo.LinQ
{
///
/// 狗狗数据类
///
public class Dog
{
public string Name; //名称
public int Price; //价格
public float Weight; //重量
///
/// 构造 —— 简化代码
///
public Dog(string name, int price, float weight)
{
Name = name;
Price = price;
Weight = weight;
}
///
/// 便于打印输出看效果 —— 简化代码
///
public override string ToString()
{
return $"{nameof(Name)}: {Name}, {nameof(Price)}: {Price}, {nameof(Weight)}: {Weight}";
}
}
}
Select —— 选择并返回相应数据类型
每帧,监听左键点击与右键点击,并选择需要返回的数据类型,打印输出!
using UniRx;
using UniRx.Triggers;
using UnityEngine;
namespace ChinarDemo.LinQ
{
public class LinQ_Select : MonoBehaviour
{
int count = 0;
///
/// 1 —— UniRx表达式
/// 点右键
///
void Start()
{
this.UpdateAsObservable()
.Where(_ => Input.GetMouseButtonDown(1)) //条件
.Select(_ => "Chinar右" + count++) //返回 字符串 —— Chinar0 / Chinar1 / Chinar...
.Subscribe(print); // print 等同于< .Subscribe(chinarEvent=>print(chinarEvent)) >
LinQ();
}
///
/// 2 —— 查询表达式
/// 点左键
///
private void LinQ()
{
(from _ in this.UpdateAsObservable() where Input.GetMouseButtonDown(0) select "Chinar左" + count++).Subscribe(print);
}
}
}
SelectMany —— 选择并返回相应数据类型,是在Select的基础上,返回了多个类型
在 UniRx 中多用于对协程执行顺序进行管理
下面例子中,将狗狗的名字拆分为字符类型,并返回
对3个协程依照需求顺序执行
public class Chinar_SelectMany : MonoBehaviour
{
private List<Dog> dogs;
///
/// 初始化函数
///
void Start()
{
dogs = new List<Dog>() //该数据用的是 1 中写好的数据
{
new Dog("金毛", 2000, 62),
new Dog("二哈", 1500, 45),
new Dog("泰迪", 1000, 15),
new Dog("吉娃娃", 500, 10)
};
dogs.ToObservable().SelectMany(_ => _.Name).Subscribe(_ => print(_)); //从列表中选择返回名字,并切分为Char类型
Chinar_UniRx();
}
private void LinQ()
{
dogs.SelectMany(_ => _.Name).ToList().ForEach(_ => print(_));
}
///
/// 在 UniRx 中的用法,可将协程以需要的顺序执行
///
private void Chinar_UniRx()
{
var ie1 = Observable.FromCoroutine(Ie1);
var ie2 = Observable.FromCoroutine(Ie2);
var ie3 = Observable.FromCoroutine(Ie3);
ie3.SelectMany(ie2.SelectMany(ie1)).Subscribe(); //协程执行顺序一一对应: 3-2-1
}
IEnumerator Ie1()
{
yield return new WaitForSeconds(0.5f);
print(1);
}
IEnumerator Ie2()
{
yield return new WaitForSeconds(0.5f);
print(2);
}
IEnumerator Ie3()
{
yield return new WaitForSeconds(0.5f);
print(3);
}
}
First —— 数据 / 事件中,满足条件的第一个
1-无论点击多少次,只会只在首次点击左键时输出 0
2-只取第一个,数组中满足条件的元素
using System.Linq;
using UniRx;
using UniRx.Triggers;
using UnityEngine;
namespace ChinarDemo.LinQ
{
public class Chinar_First : MonoBehaviour
{
private int count = 0;
void Start()
{
this.UpdateAsObservable()
.First(_ => Input.GetMouseButtonDown(0)) //第一次点击左键时
.Subscribe(_ => print(count++)); // 无论点击多少次,只会只在首次点击左键时输出 0
LinQ();
}
private void LinQ()
{
int[] numbers = {1, 2, 3, 4, 5, 6}; //数组
var numFirst = numbers.First(i => i > 3); //返回满足条件的第一个数据元素
print(numFirst); //输出 4
}
}
}
Distinct —— 数据/事件中的不同元素通过,相同元素被剔除
如:1122334 经过剔除,会变成 1234
剔除Update事件流中相同的事件
找到数字列表中不同的数字
public class Chinar_Distinct : MonoBehaviour
{
///
/// 初始化函数
///
void Start()
{
int count = 0;
//只输出一次0,因为之后的事件流,都重复了(这里剔除的是相同的事件流,而不是数字)
this.UpdateAsObservable().Distinct().Subscribe(_ => print("在 Update 事件中" + ++count + " 次数"));
LinQ();
}
private void LinQ()
{
//一个数据列表,并添加数据
List<int> ints = new List<int>()
{
1, 2, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
ints.Distinct().ToList().ForEach(_ => print(_)); //遍历输出,剔除后的列表
}
}
Last —— 最后一个元素
找到狗狗中的最后一个/满足条件狗狗中的最后一个
using System.Collections.Generic;
using System.Linq;
using ChinarX.LinQ;
using UniRx;
using UnityEngine;
public class Chinar_Last : MonoBehaviour
{
void Start()
{
List<Dog> dogs = new List<Dog>()//该数据用的是 1 中写好的数据
{
new Dog("金毛", 2000, 62),
new Dog("二哈", 1500, 45),
new Dog("泰迪", 1000, 15),
new Dog("吉娃娃", 500, 10)
};
Dog dog = dogs.Last(); //最后一个
print(dog.ToString()); //:吉娃娃
Dog dog1 = dogs.Last(_ => _.Price > 1000); //传入条件:价格在 1000以上 的狗中的最后一个
print(dog1.ToString()); //:二哈
}
}
打印输出:
Name: 吉娃娃, Price: 500, Weight: 10
Name: 二哈, Price: 1500, Weight: 45
Last —— 最后一个元素
找到狗狗中的最后一个/满足条件狗狗中的最后一个
using System.Collections.Generic;
using System.Linq;
using ChinarX.LinQ;
using UniRx;
using UnityEngine;
public class Chinar_Last : MonoBehaviour
{
void Start()
{
List<Dog> dogs = new List<Dog>()//该数据用的是 1 中写好的数据
{
new Dog("金毛", 2000, 62),
new Dog("二哈", 1500, 45),
new Dog("泰迪", 1000, 15),
new Dog("吉娃娃", 500, 10)
};
Dog dog = dogs.Last(); //最后一个
print(dog.ToString()); //:吉娃娃
Dog dog1 = dogs.Last(_ => _.Price > 1000); //传入条件:价格在 1000以上 的狗中的最后一个
print(dog1.ToString()); //:二哈
}
}
打印输出:
Name: 吉娃娃, Price: 500, Weight: 10
Name: 二哈, Price: 1500, Weight: 45
Observable.FromCoroutine(协程函数)
—— 协程转 Observable
Observable.Timer(TimeSpan.FromSeconds(1)).ToYieldInstruction()
—— Observable 转 Yield
void Start()
{
Observable.FromCoroutine(TestIEnumerator); //协程转 Observable
}
private IEnumerator TestIEnumerator()
{
yield return Observable.Timer(TimeSpan.FromSeconds(1)).ToYieldInstruction(); // 转 指令、
print("Chinar Test-Func");
}
Where()
—— 当多个事件流,需要根据逻辑满足所有都执行后,才触发执行
1:等待2个协程执行完毕
2:当所有事件执行完毕后
void Start()
{
//第一种:等待协程都执行完毕
var streamA = Observable.FromCoroutine(A);
var streamB = Observable.FromCoroutine(B);
Observable.WhenAll(streamA, streamB).Subscribe(_ => print("WenAll执行成功!"));
//第二种:所有操作执行一次后,执行以下订阅
var event1 = this.UpdateAsObservable().Where(_ => Input.GetMouseButtonDown(0)).First();
var event2 = this.UpdateAsObservable().Where(_ => Input.GetMouseButtonDown(1)).First();
Observable.WhenAll(event1, event2).Subscribe(_ => print("左右键执行一次后,执行操作!"));
}
IEnumerator A()
{
yield return new WaitForSeconds(1);
print("A");
}
IEnumerator B()
{
yield return new WaitForSeconds(2);
print("B");
}
Observable.Start()
—— 开启一个线程
ObserveOnMainThread()
—— 线程结果返回到主线程中,在主线程中观察
void Start()
{
var stream1 = Observable.Start(() =>
{
Thread.Sleep(5000);//5000毫秒
print("等待了5秒");
return 1;
}); //线程1
var stream2 = Observable.Start(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(2));
print("等待2秒");
return 2;
}); //线程2
Observable.WhenAll(stream1, stream2).ObserveOnMainThread().Subscribe(_ => //当线程执行完毕,将其他线程中的值,返回到主线程中
{
print(_[0]);
print(_[1]);
});
}
new ScheduledNotifier
—— 声明一个预定进度对象
ObserveOnMainThread()
—— 线程结果返回到主线程中,在主线程中观察
//第一个 print,请求正常信息
//第二个 print,错误信息
ObservableWWW.Get("http://www.chinar.xin/asdf").Subscribe(print, print);//请求一个错误的网路地址
void Start()
{
var slider = GameObject.Find("Slider").GetComponent<Slider>(); //滑动器
var progressText = GameObject.Find("ProgressText").GetComponent<Text>(); //进度条文本
var progressNotifier = new ScheduledNotifier<float>(); //RX 预定通知 float
ObservableWWW.GetAndGetBytes("http://www.chinar.xin/TestUpdate/granulesprite.unity3d", progress: progressNotifier).Subscribe(bytes => { }); //下载完成,做储存
progressNotifier.Subscribe(progressFloat => { slider.value = progressFloat; }); //更新进度
progressNotifier.SubscribeToText(progressText); //进度值显示在 progressText
}
Observable.Start()
—— 开启一个线程
ObserveOnMainThread()
—— 线程结果返回到主线程中,在主线程中观察
void Start()
{
var stream1 = Observable.Start(() =>
{
Thread.Sleep(4000);//4000毫秒
print("等待了4秒");
return 1;
}); //线程1
var stream2 = Observable.Start(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(2));
print("等待2秒");
return 2;
}); //线程2
Observable.WhenAll(stream1, stream2).ObserveOnMainThread().Subscribe(_ => //当线程执行完毕,将其他线程中的值,返回到主线程中
{
print(_[0]);
print(_[1]);
});
}
Observable.Start()
—— 开启一个线程
ObserveOnMainThread()
—— 线程结果返回到主线程中,在主线程中观察
void Start()
{
var stream1 = Observable.Start(() =>
{
Thread.Sleep(4000);//4000毫秒
print("等待了4秒");
return 1;
}); //线程1
var stream2 = Observable.Start(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(2));
print("等待2秒");
return 2;
}); //线程2
Observable.WhenAll(stream1, stream2).ObserveOnMainThread().Subscribe(_ => //当线程执行完毕,将其他线程中的值,返回到主线程中
{
print(_[0]);
print(_[1]);
});
}
Observable.Start()
—— 开启一个线程
ObserveOnMainThread()
—— 线程结果返回到主线程中,在主线程中观察
void Start()
{
var stream1 = Observable.Start(() =>
{
Thread.Sleep(4000);//4000毫秒
print("等待了4秒");
return 1;
}); //线程1
var stream2 = Observable.Start(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(2));
print("等待2秒");
return 2;
}); //线程2
Observable.WhenAll(stream1, stream2).ObserveOnMainThread().Subscribe(_ => //当线程执行完毕,将其他线程中的值,返回到主线程中
{
print(_[0]);
print(_[1]);
});
}
Observable.Start()
—— 开启一个线程
ObserveOnMainThread()
—— 线程结果返回到主线程中,在主线程中观察
void Start()
{
var stream1 = Observable.Start(() =>
{
Thread.Sleep(4000);//4000毫秒
print("等待了4秒");
return 1;
}); //线程1
var stream2 = Observable.Start(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(2));
print("等待2秒");
return 2;
}); //线程2
Observable.WhenAll(stream1, stream2).ObserveOnMainThread().Subscribe(_ => //当线程执行完毕,将其他线程中的值,返回到主线程中
{
print(_[0]);
print(_[1]);
});
}
Observable.Start()
—— 开启一个线程
ObserveOnMainThread()
—— 线程结果返回到主线程中,在主线程中观察
void Start()
{
var stream1 = Observable.Start(() =>
{
Thread.Sleep(4000);//4000毫秒
print("等待了4秒");
return 1;
}); //线程1
var stream2 = Observable.Start(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(2));
print("等待2秒");
return 2;
}); //线程2
Observable.WhenAll(stream1, stream2).ObserveOnMainThread().Subscribe(_ => //当线程执行完毕,将其他线程中的值,返回到主线程中
{
print(_[0]);
print(_[1]);
});
}
Chinar 提供一站式《零》基础教程 使有限时间 具备无限可能! |
Chinar 知你所想,予你所求!( Chinar Blog )
本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究
对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: [email protected]
对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址