Перемешать любой (I)List
с использованием метода расширения, основанного на Shisherle Fisher-Yates :
private static Random rng = new Random();
public static void Shuffle(this IList list)
{
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;
}
}
Использование:
List products = GetProducts();
products.Shuffle();
код выше использует сильно критикуемый метод System.Random для выбора кандидатов подкачки. Это быстро, но не так произвольно, как должно быть. Если вам нужно лучшее качество случайности в ваших тасованиях, используйте генератор случайных чисел в System.Security.Cryptography следующим образом:
using System.Security.Cryptography;
...
public static void Shuffle(this IList list)
{
RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
int n = list.Count;
while (n > 1)
{
byte[] box = new byte[1];
do provider.GetBytes(box);
while (!(box[0] < n * (Byte.MaxValue / n)));
int k = (box[0] % n);
n--;
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
В этом блоге доступно простое сравнение (WayBack Machine).
Редактирование: поскольку я пишу этот ответ пару лет назад, многие люди комментировали или писали мне, чтобы указать на большой глупый недостаток в моем сравнении. Они, конечно, правы. Нет ничего плохого в System.Random, если он используется так, как он был предназначен. В моем первом примере выше я создаю экземпляр rng-переменной внутри метода Shuffle, который запрашивает проблемы, если метод будет вызываться повторно. Ниже приведен фиксированный полный пример, основанный на действительно полезном комментарии, полученном сегодня от @weston здесь, на SO.
Program.cs:
using System;
using System.Collections.Generic;
using System.Threading;
namespace SimpleLottery
{
class Program
{
private static void Main(string[] args)
{
var numbers = new List(Enumerable.Range(1, 75));
numbers.Shuffle();
Console.WriteLine("The winning numbers are: {0}", string.Join(", ", numbers.GetRange(0, 5)));
}
}
public static class ThreadSafeRandom
{
[ThreadStatic] private static Random Local;
public static Random ThisThreadsRandom
{
get { return Local ?? (Local = new Random(unchecked(Environment.TickCount * 31 + Thread.CurrentThread.ManagedThreadId))); }
}
}
static class MyExtensions
{
public static void Shuffle(this IList list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = ThreadSafeRandom.ThisThreadsRandom.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
}
Это - веб-сервис для вызова. http://developer.yahoo.com/search/local/V2/localSearch.html
Этот сайт имеет хорошо веб-сервисы, но не точно, что Вы просите здесь. http://www.usps.com/webtools/
Если Вы, которых интенсивность потока вызовов к сервису будит слишком высоко, необходимо определенно рассмотреть получение собственного набора почтовых данных. В большинстве случаев это предоставит всю информацию, в которой Вы нуждаетесь, и существует много инструментов дб для индексации данных местоположения (т.е. PostGIS для PostgreSQL).
Любой из упомянутых онлайн-сервисов и их конкуренты предлагает "геокодирование реверса", которое делает то, что Вы спрашиваете - преобразовывают координаты lon/lat в какой-то конкретный адрес.
Если бы Вам только нужны почтовые индексы и/или города, то я получил бы базу данных почтового индекса и базу данных городской зоны из американского Бюро переписи, которое СВОБОДНО (оплаченный Вашими налоговыми поступлениями). http://www.census.gov/geo/www/cob/zt_metadata.html.
Оттуда, можно или придумать собственный алгоритм поиска для пространственных данных или использовать один из пространственные базы данных, такие как Microsoft SQL Server, PostGIS, Пространственная Oracle, ArcSDE, и т.д.
Обновление: данные переписи 2010 года могут быть найдены в: http://www2.census.gov/census_2010/
Можно купить довольно недорогую подписку индексам с lat и длинной информацией здесь: http://www.zipcodedownload.com/
Или обратное геокодирование Google
http://maps.google.com/maps/geo? output=xml&q = {0}, {1} &key = {2} &sensor=true&oe=utf8
то, где 0 широта 1, является долготой
геоимена имеют обширный набор ws, который может обработать это (среди других):
http://www.geonames.org/export/web-services.html#findNearbyPostalCodes
http://www.geonames.org/export/web-services.html#findNearbyPlaceName
Другим обратным поставщиком геокодирования, который не был перечислен здесь еще, является OpenStreetMap: можно использовать их поисковый сервис Nominatim.
OSM имеет (потенциально?) добавленная премия того, чтобы быть полностью пользователем, доступным для редактирования (подобный Wiki) и таким образом имеющий схему очень лицензирования на льготных условиях всех этих данных. Думайте об этом о данных карты с открытым исходным кодом.