-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathListExtensions.cs
164 lines (149 loc) · 7.23 KB
/
ListExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
using System;
using System.Collections.Generic;
using System.Linq;
using VInspector.Libs;
namespace UnityUtils {
public static class ListExtensions {
static Random rng;
/// <summary>
/// Xác định xem một tập hợp có null hoặc không có phần tử nào không
/// mà không cần phải đếm toàn bộ tập hợp để lấy số lượng.
///
/// Sử dụng phương thức Any() của LINQ để xác định xem tập hợp có rỗng không,
/// vì vậy có một số chi phí GC.
/// </summary>
/// <param name="list">Danh sách cần đánh giá</param>
public static bool IsNullOrEmpty<T>(this IList<T> list) {
return list == null || !list.Any();
}
/// <summary>
/// Tạo một danh sách mới là bản sao của danh sách gốc.
/// </summary>
/// <param name="list">Danh sách gốc cần được sao chép.</param>
/// <returns>Một danh sách mới là bản sao của danh sách gốc.</returns>
public static List<T> Clone<T>(this IList<T> list) {
List<T> newList = new List<T>();
foreach (T item in list) {
newList.Add(item);
}
return newList;
}
/// <summary>
/// Hoán đổi hai phần tử trong danh sách tại các chỉ số được chỉ định.
/// </summary>
/// <param name="list">Danh sách.</param>
/// <param name="indexA">Chỉ số của phần tử thứ nhất.</param>
/// <param name="indexB">Chỉ số của phần tử thứ hai.</param>
public static void Swap<T>(this IList<T> list, int indexA, int indexB) {
(list[indexA], list[indexB]) = (list[indexB], list[indexA]);
}
/// <summary>
/// Xáo trộn các phần tử trong danh sách sử dụng thuật toán Fisher-Yates với cài đặt Durstenfeld.
/// Phương thức này sửa đổi danh sách đầu vào trực tiếp, đảm bảo mỗi hoán vị có xác suất như nhau, và trả về danh sách để chuỗi phương thức.
/// </summary>
/// <param name="list">Danh sách cần được xáo trộn.</param>
/// <typeparam name="T">Kiểu của các phần tử trong danh sách.</typeparam>
/// <returns>Danh sách đã được xáo trộn.</returns>
public static IList<T> Shuffle<T>(this IList<T> list) {
if (rng == null) rng = new Random();
int count = list.Count;
while (count > 1) {
--count;
var index = rng.Next(count + 1);
list.Swap(index, count);
}
return list;
}
/// <summary>
/// Lấy một phần tử ngẫu nhiên từ danh sách.
/// </summary>
/// <typeparam name="T">Kiểu của các phần tử trong danh sách.</typeparam>
/// <param name="list">Danh sách đầu vào.</param>
/// <returns>Một phần tử ngẫu nhiên từ danh sách.</returns>
public static T GetRandom<T>(this IList<T> list)
{
if (list == null || list.Count == 0) return default(T);
return list[UnityEngine.Random.Range(0, list.Count)];
}
/// <summary>
/// Xóa và trả về phần tử cuối cùng của danh sách.
/// </summary>
/// <typeparam name="T">Kiểu của các phần tử trong danh sách.</typeparam>
/// <param name="list">Danh sách đầu vào.</param>
/// <returns>Phần tử cuối cùng đã bị xóa.</returns>
public static T PopLast<T>(this IList<T> list)
{
int[] a = new int[10];
if (list == null || list.Count == 0) throw new System.InvalidOperationException("List is empty");
T item = list[^1];
list.RemoveAt(list.Count - 1);
return item;
}
/// <summary>
/// Xóa và trả về phần tử đầu tiên của một danh sách.
///
/// Nếu danh sách rỗng, một ngoại lệ `InvalidOperationException` sẽ được ném ra.
/// </summary>
/// <typeparam name="T">Kiểu dữ liệu của các phần tử trong danh sách.</typeparam>
/// <param name="list">Danh sách cần thao tác.</param>
/// <returns>Phần tử đầu tiên đã bị xóa.</returns>
public static T PopFirst<T>(this IList<T> list)
{
if (list == null || list.Count == 0)
throw new InvalidOperationException("Danh sách không thể rỗng.");
T item = list[0];
list.RemoveAt(0);
return item;
}
/// <summary>
/// Xóa tất cả các phần tử null trong danh sách.
/// </summary>
/// <typeparam name="T">Kiểu dữ liệu của các phần tử trong danh sách.</typeparam>
/// <param name="list">Danh sách cần xóa các phần tử null.</param>
public static void RemoveAllNull<T>(this List<T> list) where T : class
{
list.RemoveAll(item => item == null);
}
/// <summary>
/// Xóa các phần tử có index nằm trong danh sách các index cần xóa.
/// </summary>
/// <typeparam name="T">Kiểu dữ liệu của các phần tử trong danh sách.</typeparam>
/// <param name="list">Danh sách cần xóa các phần tử.</param>
/// <param name="indicesToRemove">Danh sách các index cần xóa.</param>
public static void RemoveAtIndices<T>(this List<T> list, List<int> indicesToRemove)
{
indicesToRemove.Sort();
for (int i = indicesToRemove.Count - 1; i >= 0; i--)
{
list.RemoveAt(indicesToRemove[i]);
}
}
/// <summary>
/// Xóa các phần tử trong danh sách hiện tại có mặt trong danh sách các phần tử cần xóa.
/// </summary>
/// <typeparam name="T">Kiểu dữ liệu của các phần tử trong danh sách.</typeparam>
/// <param name="list">Danh sách cần xóa các phần tử.</param>
/// <param name="itemsToRemove">Danh sách các phần tử cần xóa.</param>
public static void RemoveAll<T>(this List<T> list, IEnumerable<T> itemsToRemove)
{
list.RemoveAll(item => itemsToRemove.Contains(item));
}
/// <summary>
/// Thay thế tất cả các phần tử cũ bằng phần tử mới trong danh sách.
/// </summary>
/// <typeparam name="T">Kiểu dữ liệu của các phần tử trong danh sách.</typeparam>
/// <param name="list">Danh sách cần thay thế.</param>
/// <param name="oldValue">Giá trị cần thay thế.</param>
/// <param name="newValue">Giá trị thay thế mới.</param>
public static void ReplaceAll<T>(this List<T> list, T oldValue, T newValue)
{
for (int i = 0; i < list.Count; i++)
{
if (list[i].Equals(oldValue))
{
list[i] = newValue;
}
}
}
}
}