شاید برای شما هم پیش آمده باشد که بخواهید در هر بار واکشی لیستی از اطلاعات، مثلا از دیتابیس، آیتمهای آن را بصورت تصادفی مرتب کنید.
من در پروژه اخیرم برای نمایش یک سری سوال مجبور بودم که در هر بار نمایش سوالات، لیست را به صورت رندوم مرتب کنم و به کاربر نمایش بدم. برای حصول این مهم، یک extension method به شکل زیر نوشتم:
در این تابع که اسمش را Shuffle گذاشتم، با دریافت یک لیست از نوع T، آیتمهای درون لیست را به صورت تصادفی مرتب میکند.
مثال :
در این مثال لیست x که از نوع int میباشد پس از فراخوانی Shuffle به یک لیست نامرتب تبدیل میشود که نحوه چیدمان در هر بار فراخوانی، تصادفی خواهد بود.
من در پروژه اخیرم برای نمایش یک سری سوال مجبور بودم که در هر بار نمایش سوالات، لیست را به صورت رندوم مرتب کنم و به کاربر نمایش بدم. برای حصول این مهم، یک extension method به شکل زیر نوشتم:
public static class RandomExtentions { public static void Shuffle<T>(this IList<T> list) { Random rng = new Random(); Thread.Sleep(100); int n = list.Count; while (n > 1) { n--; int k = rng.Next(n + 1); T value = list[k]; list[k] = list[n]; list[n] = value; } } }
مثال :
var x =new List<int>(); x.Add(1); x.Add(2); x.Add(3); x.Add(4); x.Add(5); x.Shuffle();
نظرات مطالب
ASP.NET MVC #17
مراجعه کنید به مطلب «چک لیست تهیه یک برنامه ASP.NET MVC».
نظرات مطالب
ELMAH و حملات XSS
سلام
این چک لیست توسط آقای نصیری تهیه شده بود. این مورد هم از نظر من معتبر است.
با تشکر
لیست خلاصه ای نکات بهرهوری گفته شده از اسکات هانسلمن که در بلاگ آقای دنی شریبر آورده شده و دوباره توسط هانسلمن در بلاگ خودشان ارائه گردیده. در ادامه نیز جملاتی که از ایشان در متن بوده که در زیر آورده شده
- تفاوت بین "اثربخشی": انجام کارهای درست و "بهروری": انجام درست کارها
- امید نقشه نیست، امید چیزی نیست جز انتظار کشیدن و اجازه دادن به زندگی که برای شما اتفاق بیفتد
- تفاوت بین "اثربخشی": انجام کارهای درست و "بهروری": انجام درست کارها
- امید نقشه نیست، امید چیزی نیست جز انتظار کشیدن و اجازه دادن به زندگی که برای شما اتفاق بیفتد
گاهی از اوقات نیاز میشود تا در یک لیست، آیتمهای تکراری موجود را مشخص کرد. به صورت پیش فرض متد Distinct برای حذف مقادیر تکراری در یک لیست با استفاده از LINQ موجود است که البته آنهم اما و اگرهایی دارد که در ادامه به آن پرداخته خواهد شد، اما باز هم این مورد پاسخ سؤال اصلی نیست (نمیخواهیم موارد تکراری را حذف کنیم).
برای حذف آیتمهای تکراری از یک لیست جنریک میتوان متد زیر را نوشت:
public static List<T> RemoveDuplicates<T>(List<T> items)
{
return (from s in items select s).Distinct().ToList();
}
public static void TestRemoveDuplicates()
{
List<string> sampleList =
new List<string>() { "A1", "A2", "A3", "A1", "A2", "A3" };
sampleList = RemoveDuplicates(sampleList);
foreach (var item in sampleList)
Console.WriteLine(item);
}
public class Employee
{
public int ID { get; set; }
public string FName { get; set; }
public int Age { get; set; }
}
public static void TestRemoveDuplicates()
{
List<Employee> lstEmp = new List<Employee>()
{
new Employee(){ ID=1, Age=20, FName="F1"},
new Employee(){ ID=2, Age=21, FName="F2"},
new Employee(){ ID=1, Age=20, FName="F1"},
};
lstEmp = RemoveDuplicates<Employee>(lstEmp);
foreach (var item in lstEmp)
Console.WriteLine(item.FName);
}
برای رفع این مشکل باید از آرگومان دوم متد distinct جهت معرفی وهلهای از کلاسی که اینترفیس IEqualityComparer را پیاده سازی میکند، کمک گرفت.
public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer);
public class EmployeeComparer : IEqualityComparer<Employee>
{
public bool Equals(Employee x, Employee y)
{
//آیا دقیقا یک وهله هستند؟
if (Object.ReferenceEquals(x, y)) return true;
//آیا یکی از وهلهها نال است؟
if (Object.ReferenceEquals(x, null) ||
Object.ReferenceEquals(y, null))
return false;
return x.Age == y.Age && x.FName == y.FName && x.ID == y.ID;
}
public int GetHashCode(Employee obj)
{
if (Object.ReferenceEquals(obj, null)) return 0;
int hashTextual = obj.FName == null ? 0 : obj.FName.GetHashCode();
int hashDigital = obj.Age.GetHashCode();
return hashTextual ^ hashDigital;
}
}
public static List<T> RemoveDuplicates<T>(List<T> items, IEqualityComparer<T> comparer)
{
return (from s in items select s).Distinct(comparer).ToList();
}
public static void TestRemoveDuplicates()
{
List<Employee> lstEmp = new List<Employee>()
{
new Employee(){ ID=1, Age=20, FName="F1"},
new Employee(){ ID=2, Age=21, FName="F2"},
new Employee(){ ID=1, Age=20, FName="F1"},
};
lstEmp = RemoveDuplicates(lstEmp, new EmployeeComparer());
foreach (var item in lstEmp)
Console.WriteLine(item.FName);
}
سؤال: برای یافتن آیتمهای تکراری یک لیست چه باید کرد؟
احتمالا مقاله "روشهایی برای حذف رکوردهای تکراری" را به خاطر دارید. اینجا هم میتوان کوئری LINQ ایی را نوشت که رکوردها را بر اساس سن، گروه بندی کرده و سپس گروههایی را که بیش از یک رکورد دارند، انتخاب نماید.
public static void FindDuplicates()
{
List<Employee> lstEmp = new List<Employee>()
{
new Employee(){ ID=1, Age=20, FName="F1"},
new Employee(){ ID=2, Age=21, FName="F2"},
new Employee(){ ID=1, Age=20, FName="F1"},
};
var query = from c in lstEmp
group c by c.Age into g
where g.Count() > 1
select new { Age = g.Key, Count = g.Count() };
foreach (var item in query)
{
Console.WriteLine("Age {0} has {1} records", item.Age, item.Count);
}
}
با آمدن SQL server 2008 استفاده از کتابخانه SQL-DMO برای انجام یک سری از امور بر روی اس کیوال سرور با استفاده از برنامه نویسی منسوخ شد. یکی از تواناییهای این کتابخانه لیست کردن سرورهای اس کیوال (قابل دسترسی) موجود در شبکه بود.
برای مثال توسط این کتابخانه به صورت زیر میتوان اینکار را انجام داد:
در قطعه کد زیر فرض بر این است که ارجاعی به کتابخانه sqldmo را در برگه com مربوط به project->add reference اضافه کردهاید:
using SQLDMO;
using System.Collections.Generic;
public static List<string> GetSQLServersList2()
{
List<string> result = new List<string>();
ApplicationClass sqlApp = new ApplicationClass();
NameList lst = sqlApp.ListAvailableSQLServers();
for (int i = 1; i <= lst.Count; i++)
result.Add(lst.Item(i));
lst = null;
sqlApp = null;
return result;
}
using System.Collections.Generic;
using System.Data;
using System.Data.Sql;
public class CListServers
{
public static List<string> GetSQLServersList()
{
List<string> result = new List<string>();
// Retrieve the enumerator instance and then the data.
var instance = SqlDataSourceEnumerator.Instance;
var table = instance.GetDataSources();
// Display the contents of the table.
foreach (DataRow row in table.Rows)
{
result.Add(string.Format("{0}\\{1}", row[0], row[1]));
}
return result;
}
}
کتابخانه COM یاد شده (SQL-DMO) در SQL server 2008 با کتابخانه SMO جایگزین شده است.
در این حالت خواهیم داشت:
using System.Collections.Generic;
using System.Data;
using Microsoft.SqlServer.Management.Smo;
public class CListServers
{
public static List<string> GetSQLServersListSMO()
{
List<string> result = new List<string>();
DataTable dt = SmoApplication.EnumAvailableSqlServers(false);
if (dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
result.Add(dr["Name"].ToString());
}
}
return result;
}
}