Cannot convert List<List<double>> to List<double> - c#

I created a list which has 100 list each with 60 values, I need to run all of those 6000 values held within the list called population through a test (shown at the bottom error) and im not sure how i would go about converting the List<List<double>> to List<double>, or if i even can

You can either start off with a List<double> and use AddRange, so that you flatten the collections. Or you can convert it using SelectMany, like this:
var list = new List<double>();
foreach (...)
{
list.AddRange(someOtherList);
}
// Or
var list = new List<List<double>>();
var flattenedList = list.SelectMany(x => x);

I saw your code and think the following code can help you.
class Program
{
public static Random _random = new Random();
static void Main(string[] args)
{
List<List<double>> population = new List<List<double>>();
for (int k = 0; k < 100; k++)
{
var gWeights = new List<double>();
for (int i = 0; i < 60; i++)
{
var random = (_random.NextDouble() * 2) - 1;
gWeights.Add(random);
}
population.Add(gWeights);
}
List<double> population2 = new List<double>();
population.ForEach(x => population2.AddRange(x));
GetResult(population2);
Console.ReadKey();
}
public static void GetResult(List<double> items)
{
//your code
}
}

Related

Take 30 random elements from list

I have a list of strings containing loads of hashtags with texts.
ex #csharp #java ect.
each hashtag is a own string in a List. I now want to randomly always console.writeline 30 items of that list.
List
List<string> Hashtags = new List<string>();
Writeline
foreach (var x in Hashtags) {
Console.WriteLine(x);
}
Ideally i never wanna have the same hashtag in the random 30.
You should try this:
var rnd = new Random();
foreach (var x in Hashtags.OrderBy(x => rnd.Next()).Take(30))
{
Console.WriteLine(x);
}
This has O(n^2) complexity, but is easily readable.
If you want efficiency try a Fisher-Yates Shuffle, it's O(n), but less readable:
var take = 30;
var rnd = new Random();
for (var i = 0; i < (Hashtags.Count < take ? Hashtags.Count : take); i++)
{
var j = rnd.Next(Hashtags.Count);
(Hashtags[i], Hashtags[j]) = (Hashtags[j], Hashtags[i]);
}
foreach (var x in Hashtags.Take(take))
{
Console.WriteLine(x);
}
Keep in mind, though, that it's best to instantiate Random once per thread, so this would be a better way:
[ThreadStatic]
private static Random rnd = new Random();
This should do. It is efficient, as it shuffles only the required amount of items, not the whole collection. You pass how many elements you want to fetch from the array as parameter(elementCount).
private static Random randomGenerator = new Random();
static void Main()
{
var hashtags = new List<string>() { "c#", "javascript", "ef", "asp.net" };
var result = GetRandomItems<string>(hashtags, 2);
foreach (var item in result)
{
Console.WriteLine(item);
}
}
private static IEnumerable<T> GetRandomItems<T>(IEnumerable<T> collection, int elementCount)
{
var collectionCount = collection.Count();
if (elementCount > collectionCount)
{
elementCount = collectionCount;
}
var collectionCopy = collection.ToList();
var randomIndex = randomGenerator.Next(0, collectionCopy.Count);
for (var index = 0; index < elementCount; index++)
{
var tempElement = collectionCopy[index];
collectionCopy[index] = collectionCopy[randomIndex];
collectionCopy[randomIndex] = tempElement;
randomIndex = randomGenerator.Next(index + 1, collectionCopy.Count);
}
return collectionCopy.Take(elementCount);
}
Call 30 times Random.next
https://learn.microsoft.com/en-us/dotnet/api/system.random.next
var random = new Random();
//calls this n times in a loop:
Console.writeline(Hashtags[random.next(Hashtags.Count])
Got it working myself, little more verbose but hopefully easier to follow.
var random = new Random();
var uniques = Hashtags;
for (var i = 0; i < 30; i++) {
var index = random.Next(0, uniques.Count());
Console.WriteLine(uniques[index]);
uniques.RemoveAt(index);
}

How can I add same numbers in existing list?

My function to generate random numbers is this:
public static List<int> GetRandomNumbers(int count)
{
HashSet<int> randomNumbers = new HashSet<int>();
Random random = new Random();
for (int i = 0; i < count; i++)
{
while(!randomNumbers.Add(random.Next(100, 999)));
}
return randomNumbers.ToList();
}
This is how I call it:
private void button1_Click(object sender, EventArgs e)
{
List<int> list = new List<int>();
list = GetRandomNumbers(5);
for (int i = 0; i < list.Count; i++)
{
MessageBox.Show(list[i].ToString());
}
}
Ok, so, what I want to do is, for example, if the list generated is the following:
152 582 254 891 421
I want to make the list be:
152 152 582 582 254 254 891 891 421 421
Basically, each number to be added one more time after itself in the list. How can I do this? (It would be good if you include a simple way to do this considering time not a problem, and maybe a better way to save time)
Thanks
Your question is unclear.
You can take a list (not a HashSet) with repeating elements and move every repetition to immediately follow the first occurrence like this:
var numbers = Enumerable.Range(1, count).Select(i => random.NextInt(0, 300));
return numbers.GroupBy(i => i).SelectMany(s => s).ToList();
You can take an existing list and make each element repeat twice like this:
list.SelectMany(o => Enumerable.Repeat(o, 2));
You could change your function slightly to:
private static Random random = new Random();
public static List<int> GetRandomNumbers(int count)
{
int value;
List<int> values = new List<int>();
HashSet<int> randomNumbers = new HashSet<int>();
for (int i = 0; i < count; i++)
{
while (!randomNumbers.Add(value = random.Next(100, 999)));
values.Add(value);
values.Add(value);
}
return values;
}
I think you just want something like this:
var list2 = new List<int>(list1.Count * 2);
foreach (var n in list1)
{
list2.Add(n);
list2.Add(n);
}
That will loop through the list and put each value into the second list twice.
I think you need to change your function as follows:
public static List<int> GetRandomNumbers(int count)
{
List<int> Result = new List<int>();
Random random = new Random();
for (int i = 0; i < count; i++)
{
int NewNumber = random.Next(100, 999);
Result.Add(NewNumber);
Result.Add(NewNumber);
}
return Result;
}
I tried the function above, it worked just like you said.

Select a number randomly from 1 to 99

I want to select a random number from 1 to 99. And then select the number again but this time discard the previous number. Can someone help me.
private List<int> numbers = Enumerable.Range(0, 100).ToList();
private Random rnd = new Random();
public int GetRandomInt()
{
var index = rnd.Next(0, numbers.Length);
var number = numbers[index];
numbers.RemoveAt(index);
return number;
}
Here's what I'd do:
var rnd = new Random();
var numbers = new Stack<int>(Enumerable.Range(1, 99).OrderBy(x => rnd.Next()));
You effectively are randomizing the list of numbers and then adding them to a stack. Now you just have to do this to get each number:
var next = numbers.Pop()
You stop when numbers.Count == 0. Simple.
Here is the revised version of Khanh TO, because it is not correct:
List<int> usedNumbers = new List<int>();
Random rand = new Random(new object().GetHashCode());
int number = 0;
for (int i = 0; i < 99; i++)
{
do
{
number = 1 + rand.Next(0, 99);
} while (usedNumbers.Contains(number));
usedNumbers.Add(number);
}
I usually do it with arrays.
Whenever you create a random number just put on the array. so next time check if the number is already generated by checking in the array.
Try this
IList<int> arr = Enumerable.Range(1, 99).ToList();
int randNum;
Random rnd = new Random();
randNum = rnd.Next(1, arr.Count());
MessageBox.Show(randNum.ToString());
arr = arr.Where(x => x != randNum).ToList();
Can I go for the shortest code, without a nested loop, or removing list elements.
Code 1
class Program
{
static Random rnd=new Random();
static void Main(string[] args)
{
var list=new SortedDictionary<double, int>();
// Fill list
for (int i=1; i<=99; i++)
{
list.Add(rnd.NextDouble(), i);
}
// List Automatically random
var random_int=list.Values.ToArray();
// random_int = {45, 7, 72, .. }
}
}
Code 2
class Program
{
static Random rnd=new Random();
static void Main(string[] args)
{
var list=new int[99];
// Fill list
for (int i=1; i<=99; i++)
{
list[i-1]=i;
}
Comparison<int> any=(x, y) =>
{
var z=2*rnd.NextDouble()-1;
return z.CompareTo(0);
};
// Randomize List
Array.Sort(list, any);
// list = { 49, 59, 21, 7, 18 ...}
}
}

How To Get Distinct Lists?

With the lists below, how can I get the distinct lists from the lists below without doing a full brute-force comparison? In the example, list2 and list3 are identical, so I would only want list1 and list2.
var list1 = new List<int>{1,2,3,4,5};
var list2 = new List<int>{2,3};
var list3 = new List<int>{3,2};
Replace the lists with a collection of HashSets.
You can then write
hashSets.Distinct(HashSet<int>.CreateSetComparer())
EDIT Use List<>.Sort + IEnumerable's .Any and .SequenceEqual
public static List<List<int>> Test1(List<int>[] lists)
{
var result = new List<List<int>>();
foreach(var list in lists)
{
list.Sort();
if(!result.Any(elm => elm.SequenceEqual(list)))
result.Add(list);
}
return result;
}
Here's a simple benchmark/test showing the HashSet method and the pre-.Sort .Any .SequenceEqual method. edit http://ideone.com/x3CJ8I of course ideone probably isn't the best benchmarking platform so feel free to run it on your own machine.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
public class Demo
{
public static void Main()
{
int tries = 100;
int count = 50;
int size = 1000;
Random rnd = new Random();
List<int>[] list;
Stopwatch sw;
sw = new Stopwatch();
for(int x=0; x<tries; x++)
{
list = new List<int>[count];
for(int y=0; y<count; y++)
{
list[y] = new List<int>();
for(int z=0; z<size; z++)
{
int n = rnd.Next();
list[y].Add(n);
}
if((y % 5) == 0 && y > 0)
{ // make repeated lists for the uniqueness check
list[y-1] = new List<int>(list[y]);
list[y-1].Reverse();
}
}
sw.Start();
Test1(list);
sw.Stop();
}
Console.WriteLine( sw.Elapsed.ToString() );
sw = new Stopwatch();
for(int x=0; x<tries; x++)
{
list = new List<int>[count];
for(int y=0; y<count; y++)
{
list[y] = new List<int>();
for(int z=0; z<size; z++)
{
int n = rnd.Next();
list[y].Add(n);
}
if((y % 5) == 0 && y > 0)
{ // make repeated lists for the uniqueness check
list[y-1] = new List<int>(list[y]);
list[y-1].Reverse();
}
}
sw.Start();
Test2(list);
sw.Stop();
}
Console.WriteLine( sw.Elapsed.ToString() );
}
public static List<List<int>> Test1(List<int>[] lists)
{
var result = new List<List<int>>();
foreach(var list in lists)
{
list.Sort();
if(!result.Any(elm => elm.SequenceEqual(list)))
result.Add(list);
}
return result;
}
public static List<HashSet<int>> Test2(List<int>[] lists)
{
var result = new List<HashSet<int>>();
foreach(var list in lists)
{
result.Add(new HashSet<int>(list));
}
result = result.Distinct(HashSet<int>.CreateSetComparer()).ToList();
return result;
}
}
EDIT I had time to modify the test, turns out the overhead of creating HashSets + .Distinct is edit EVERY SIMILAR to that of .Sort + .Any + .SequenceEqual. http://ideone.com/x3CJ8I
You could also concat the three lists and then do a .Distinct()
list<int> newList = list1.Concat(list2.Concat(list3)).Distinct();

Sorting a List<int>

Using C# what is the best way to sort a List numerically?
my list has items 5,7,3 and I would like them sorted 3,5,7. I know some longer ways, but I would imagine linq has a quicker way?
sorry this was end of day, my mind is else where it worked, didn't see it change the first time:(
There's no need for LINQ here, just call Sort:
list.Sort();
Example code:
List<int> list = new List<int> { 5, 7, 3 };
list.Sort();
foreach (int x in list)
{
Console.WriteLine(x);
}
Result:
3
5
7
Keeping it simple is the key.
Try Below.
var values = new int[5,7,3];
values = values.OrderBy(p => p).ToList();
var values = new int[] {5,7,3};
var sortedValues = values.OrderBy(v => v).ToList(); // result 3,5,7
List<int> list = new List<int> { 5, 7, 3 };
list.Sort((x,y)=> y.CompareTo(x));
list.ForEach(action => { Console.Write(action + " "); });
Sort a list of integers descending
class Program
{
private class SortIntDescending : IComparer<int>
{
int IComparer<int>.Compare(int a, int b) //implement Compare
{
if (a > b)
return -1; //normally greater than = 1
if (a < b)
return 1; // normally smaller than = -1
else
return 0; // equal
}
}
static List<int> intlist = new List<int>(); // make a list
static void Main(string[] args)
{
intlist.Add(5); //fill the list with 5 ints
intlist.Add(3);
intlist.Add(5);
intlist.Add(15);
intlist.Add(7);
Console.WriteLine("Unsorted list :");
Printlist(intlist);
Console.WriteLine();
// intlist.Sort(); uses the default Comparer, which is ascending
intlist.Sort(new SortIntDescending()); //sort descending
Console.WriteLine("Sorted descending list :");
Printlist(intlist);
Console.ReadKey(); //wait for keydown
}
static void Printlist(List<int> L)
{
foreach (int i in L) //print on the console
{
Console.WriteLine(i);
}
}
}
Sort list of int descending you could just sort first and reverse
class Program
{
static void Main(string[] args)
{
List<int> myList = new List<int>();
myList.Add(38);
myList.Add(34);
myList.Add(35);
myList.Add(36);
myList.Add(37);
myList.Sort();
myList.Reverse();
myList.ForEach(Console.WriteLine);
}
}
double jhon = 3;
double[] numbers = new double[3];
for (int i = 0; i < 3; i++)
{
numbers[i] = double.Parse(Console.ReadLine());
}
Console.WriteLine("\n");
Array.Sort(numbers);
for (int i = 0; i < 3; i++)
{
Console.WriteLine(numbers[i]);
}
Console.ReadLine();

Categories