Consider i have ArrayLists like these,
1){int[],int,int[]}
2){int[],int[],int}
And i have a count, 'n'. If n is 3 then my arrayList should be,
1){int[],int[],int[],int,int[],int[],int[]}
2){int[],int[],int[],int[],int[],int[],int}
i.e The new ArrayList should contain 'n' times the Array int[].
For one thing, do you really have to use an ArrayList? The fact that you're holding different types of data in one collection suggests there's probably a better way of solving your problem. Anyway, you could do something like this:
public static ArrayList DuplicateIntArrays(ArrayList input, int copies)
{
ArrayList ret = new ArrayList();
foreach (object element in input)
{
if (element is int[])
{
for (int i=0; i < copies; i++)
{
ret.Add(element);
}
}
else
{
ret.Add(element);
}
}
return ret;
}
Related
Can a 'generic type' be an array?
And in the cases where it is, how can one access that array?
Can you access a given generic type T as an array, when it is one, and as a non-array when it is not one?
For instance:
If I had a method like ->
void MustBeOfType<T>(T value){}
Can I have ->
MustBeOfType<int>(10);
And Also ->
MustBeOfType<int[]>( new int[] { 1, 2, 3 } );
And within those generic methods, can they access the values as one would expect? - one as an int and one as an int[]?
I think there might be something with typeof(T).IsArray()... but I just can't for the life of me figure out how to cast the parameter as an array when it is one.
Thanks!
You could...but, I'm not sure you should:
void MustBeOfType<T>(T value)
{
Array array = value as Array;
if (array != null) //It is an array
{
foreach (var arrayItem in array)
{
}
for (int i = 0; i < array.Length; i++)
{
var arrayItem = array.GetValue(i);
}
}
else //It is not an array
{
}
}
I am not sure what you are trying to do but Generic types can be anything. You can put restrictions to your generic type with where clause, but this is up to you and up to functionality and context.
Lets take List as example. Let say that we have List inside List. Then we define it as:
List<List<string>> myListOfList = new List<List<string>>();
your must be of type can also be anything ( if you didnt put restriction with where clause)
MustBeOfType<int[][]>()
MustBeOfType<List<List<string>>>()
MustBeOfType<AnyOtherGenericClass<List<string>>>()
and to be able to access it:
class MustBeOfType<T>
{
private T _value;
MustBeofType(T value)
{
_value = value;
}
}
to be able to make operation on , you can use reflection or if you put where restriction and your where restriction has Type, then you can see properties of that Type.
The problem is to return a list containing all permutations of an array. For some reason the result list is empty. The truth is I'm 100% sure it has to do with me using IList or List wrong somewhere, but it was honestly confusing to have to return it as an IList<IList<int>> ...I feel like it would have been easier to just return List<List<int>> but I'm doing this off of leetcode and trying to keep the original signature that was written in the question. When currentPermutation.Count == nums.Length, I printed the values of the currnet permutation and it printed all permutations, so I know that currentPermutation is being filled with the corrent numbers..why isn't the result list doing it as well?
public class Solution {
public IList<IList<int>> Permute(int[] nums) {
List<IList<int>> listOfPermutations = new List<IList<int>>();
IList<int> currentPermutation = new List<int>();
int[] elementsSeen = new int[nums.Length];
Permute(listOfPermutations, nums, elementsSeen, currentPermutation);
return (IList<IList<int>>)listOfPermutations;
}
public void Permute(List<IList<int>> list, int[] nums, int[] elementsSeen, IList<int> currentPermutation) {
if (currentPermutation.Count == nums.Length) {
list.Add(currentPermutation);
}
else {
for (int i = 0; i < nums.Length; i++) {
if (elementsSeen[i] == 0) {
elementsSeen[i] = 1;
currentPermutation.Add(nums[i]);
Permute(list, nums, elementsSeen, currentPermutation);
currentPermutation.RemoveAt(currentPermutation.Count - 1);
elementsSeen[i] = 0;
}
}
}
}
}
You add the same List over and over to the result. In the end you have n! pointers to the same, empty List (currentPermutation is empty in the end). All you need is to make a copy of the List for every permutation and add the new List to the result.
list.Add(currentPermutation.ToList()); //clone the list
"calling ToList() on a List" may seem a bit tricky, you are actually calling ToList() on IEnumerable, is that better? The point is to create new, independent List.
Maybe you do not exactly understand what List in C# is. List is an object. If you add it somewhere, you do not add it literally there, you just add pointer to this object.
I have been writing a program which has a list of 100,000 elements I have to process all the elements with different conditions. This does not take much time 3sec at most. After this I have a list of valid entries and my orignal list which had 100000 elements. The new list usualy has a size of 6K - 7K. The main problem is when I use List.Remove function or any other way to remove the invalid elements from the orignal list with 100K elements its too slow.
Please guide if I should use any thing else then the LIST or there is something that I can do with this code also.
I am including all codes I tried.
for( int k = 0; k < initialList.Count;k++)
{
combo c = initialList.ElementAt(k);
if(invalidEntries.Contains(c))
{
smartString.Append(c.number1.ToString());
smartString.Append(c.number2.ToString());
smartString.Append(c.number3.ToString());
smartString.Append(c.number4.ToString());
smartString.Append(c.number5.ToString());
smartString.Append(" Sum : ");
smartString.Append(c.sum.ToString());
smartString.AppendLine();
InvalidCombo.AppendText(smartString.ToString());
smartString.Clear();
}
else
{
smartString.Append(c.number1.ToString());
smartString.Append(c.number2.ToString());
smartString.Append(c.number3.ToString());
smartString.Append(c.number4.ToString());
smartString.Append(c.number5.ToString());
smartString.Append(" Sum : ");
smartString.Append(c.sum.ToString());
smartString.AppendLine();
validCombo.AppendText(smartString.ToString());
smartString.Clear();
}
}
Also
for(int k=0;k<100000;k++)
{
combo c = initialList.ElementAt(k);
if (!invalidEntries.Contains(c))
validEntries.Add(c);
}
I have also tried the .remove functions but i think list cant take it. so any suggestions/solutions?
I'm a big fan of the structs, but you must be very careful when you work with a struct like yours. The List<T> methods that rely on equality (Contains, IndexOf, Remove) may not work and should not be used. Same for HashSet<T> and similar.
The best for your case would be to combine the processing with the removal. And the fastest way to do a removal from a List<T> is to not use it's item remove related (Remove/RemoveAt) methods! :-) Instead, you "compact" the list by keeping the items that should remain (and their count) at the beginning of the list, and then just use RemoveRange method to cut the unnecessary items at the end of the list. This is very efficient and avoids all the data block moving which happens when you use the "normal" list remove methods. Here is a sample code based on your struct definition:
public struct combo { public int number1; public int number2; public int number3; public int number4; public int number5; public int sum; public bool invalid; }
void ProcessList(List<combo> list)
{
int count = 0;
for (int i = 0; i < list.Count; i++)
{
var item = list[i];
ProcessItem(ref item);
if (!item.invalid) list[count++] = item;
}
list.RemoveRange(count, list.Count - count);
}
void ProcessItem(ref combo item)
{
// do the processing and set item.invalid=true/false
}
In case you are not mutating the item inside the ProcessItem, you can remove the ref modifier, change the return type to bool and use it to control whether the item should be removed from the list or not.
Here is an example of using HashSet. It is very fast.
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var myInts = new HashSet<int>();
for (var i = 0; i < 100000; i++)
myInts.Add(i);
myInts.Remove(62345);
}
}
}
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
how to inset a new array to my jagged array
i have a problem, where i dont know how i can make a string array variable in array length.
i have this code now below:
string[] p = new string[10];
int num = 0;
foreach (Product products in GetAllProducts())
{
//do something
p[num]= "some variable result"
num++
}
The problem is, that i dont know how many of "p" i will get, although i know it atleast will be less than 10.
but if i put it on 0, i will get an error when i start it, because it doesn't know the "p[num]"
So i am looking for some way to make "p" have a variable length.
anyone could help me out a bit? thanx
============Solved==========
List<string> p = new List<string>();
int num = 0;
foreach (Product products in GetAllProducts())
{
string s= null;
//do something ( create s out of multiple parts += s etc.)
p.add(s)
num++
}
thanx to solution poster
Use an List<string> instead of an array, if you do not know the number of items you will need to add.
Your array length cannot be modified after it has been instantiated. Use ArrayList or Generic Lists.
var p = new new List<string>(10);
foreach (Product products in GetAllProducts())
{
//do something
p.Add("some variable result");
}
What does GetAllProducts() return? Does it have a count or a length?! You should call that first, save it in a variable, get the count/length and then declare your array!
There's two solution.
If you want to keep using array :
int num = 0;
var list = GetAllProducts();
string[] p = new string[list.Length]; // Or list.Count if this is a collection
foreach (Product products in list)
{
//do something
p[num] = "some variable result";
num++;
}
Otherwise you should use a List like this :
List<string> p = new List<string>();
foreach (Product products in GetAllProducts())
{
//do something
p.Add("some variable result");
}
Use Array.Resize() method, which allows to resize it (by n number of indexes).
In my exmaple I will reize by 1 on each step of the way:
string[] array = new string[3]; //create array
for (int i = 0; i < 5; i++)
{
if (array.Length-1 < i) //checking for the available length
{
Array.Resize(ref array, array.Length + 1); //when to small, create a new index
}
array[i] = i.ToString(); //add an item to array[index] - of i
}
Because your code is using a foreach on the result from GetAllProducts, then GetAllProducts must be returning a IEnumerable collection. Probably the best solution would be to simply assign the result of GetAllProducts to such a collection. For example, perhaps it already returns a list of strings? So you can do:
List<string> strings = GetAllProducts();
There is no need to have a foreach loop to create an array when you already have a collection anyway being returned from GetAllProducts.
Or simply:
var strings = GetAllProducts();
to let the compiler work out the type of strings.
Most things you can do with an array you can also do with a List, and some more (such as adding items to the end of the List).
Perhaps you can post the signature of GetAllProducts (especially its return type) so we can better advise you?
I see many gave you the right answer which is the use of Lists. If you still need an array in the end, you can easily convert your list into an Array like this :
string[] tempArray = myList.ToArray();
from my function below, I am returning an array. In C# how would I consume that array?
public Array arrayFucntion()
{
// do something
foreach (var Objs in items)
{
list.Add(Objs.value1);
}
string[] myArray = list.ToArray();
MessageBox.Show(myArray.ToString());
return myArray;
}
Now how would I use it in a function like below
void consumeFunction()
{
var x = arrayFucntion();
// what do do to see values of the array
}
Return a string[], then you can do the for loop through the string array.
public string[]arrayFucntion()
void consumeFunction()
{
var x = arrayFucntion();
for (int i=0; i<x.Lenght; i++)
{
x[i]...
}
}
Make the return type string[] instead of Array.
You can iterate through the members:
foreach (string sArrayMember in x)
{
// Do something with s
}
You can also access any of the properties or members listed in the MSDN documentation, including Copy, Find, and Sort.
x is now an array object...
you can do foreach on it, or use linq.....or using direct addressing x[0]