I need to get an array containing reversed alternate elements of the original array.
For example: an array containing elements {12,56,67}.
I need to get an array containing {67,12}
(reversing array to get {67,56,12} then take alternate elements means {67,12})
I need to do this in c#
This won't be the shortest answer you'll get, but it seems fairly optimised to me.
int[] rgIn = new int[]{0,1,2,3,4,5};
int[] rgOut = new int[rgIn.Length / 2];
int ixOut = 0;
for (int ixIn = rgIn.Length - 2; ixIn >= 0; ixIn -= 2)
{
rgOut[ixOut++] = rgIn[ixIn];
}
If you're using C# 3, try this:
int[] array = {1,2,3,4,5,6};
var x = array.Reverse().Where( (n,i) => i % 2 !=0);
Where is an extension method (new in C# 3.0) which forms part of a language feature called LINQ. It filters a sequence based on a predicate. In the sample above, n is the element of the sequence and i is the zero based index of the element in the sequence. Both are strongly typed. The predicate i%2!=0 is saying that the index of the element is not directly divisible by 2, so what we are saying is reverse the list and select the odd elements from it.
Not the most efficient solution, but short and concise.
Related
I have a method that accepts an IEnumerable as a parameter.
My issue is that this method is sometimes given an array that starts at 1 (instead of 0).
I could just create a list and add the elements of the parameter to it but isn't there a way of just getting the first index?
EDIT 1:
What I mean with "an array that starts at 1" is an array that literally starts at 1, for example:
I cannot access the array "cells" with the line:
cells[0, 0]
This specific array is being read from an Excel range.
EDIT 2:
This isn't the only array that is being given to The method.
The method also receives arrays that start at 0 and it needs to work for all cases.
Normally arrays have a lower bound of 0. However, you can create arrays with different lower bounds. To do that you need to use Array.CreateInstance:
var array = Array.CreateInstance(typeof(string), new[] { 10 }, new[] { 1 });
This will create an one dimensional array with ten elements with a lower bound of 1. Here is how you set the value of the first element:
array.SetValue("first", 1);
In your case you could use code like this to create a two dimensional array with 10 x 20 elements and lower bounds of 1:
var array = (object[,]) Array.CreateInstance(typeof(object), new[] { 10, 20 }, new[] { 1, 1 });
And to get the lower bound of the first dimension you can use GetLowerBound:
var lowerBound = array.GetLowerBound(0);
Specify 1 as the argument to get the lower bound of the second dimension etc. There is also a GetUpperBound method. And in case you don't even know the dimensions of the array you can inspect the Rank property.
I believe this feature mostly exist to support porting old Visual Basic code to Visual Basic .NET and interop with COM automation (e.g. Excel) where arrays often have a lower bound of 1.
I don't understand what do you mean by .
sometimes given an array that starts at 1
The arrays must start at the zero index,
I think you mean to try to filter the values and check if null empty values
you can try the below:
var firstValue = array.First(x => !string.IsNullOrWhiteSpace(x.value));
Or you can remove the first element or any element on a condition
array = array.Skip(0);
UPDATE
When you pass a sub-array to the method, usually it doesn't start at index zero.
So, you can loop on the array to and handle the items after checking if it exists or not using ElementAtOrDefault() Linq method.
for (int i = 0; i < array.length; i++)
{
if(ElementAtOrDefault(i) != null)
// your logic
}
As #MartinLiversage pointed out, there is an overload of Array.CreateInstance allowing to specify a lower bound:
public static Array CreateInstance (Type elementType, int[] lengths, int[] lowerBounds);
You have to cast the unspecific Array to a concrete type, to able to access its elements directly. Example:
var cells =
(int[,])Array.CreateInstance(typeof(int), new[] { ROWS, COLUMNS }, new[] { 1, 1 });
You can get the bounds with cells.GetLowerBound(0) (first dimension) and cells.GetLowerBound(1) (second dimension). There is a corresponding GetUpperBound method. Example:
// Loop through the matrix
for (int i = cells.GetLowerBound(0); i <= cells.GetUpperBound(0); i++) {
for (int j = cells.GetLowerBound(1); j <= cells.GetUpperBound(1); j++) {
// Get an element
var element = cells[i, j];
// Set an element
cells[i, j] = value;
}
}
Or, to get the first element only:
var result = cells[cells.GetLowerBound(0), cells.GetLowerBound(1)];
You can also enumerate the array with foreach. This flattens the array, i.e. it treats the array as if it was one-dimensional.
Note, the LINQ extension method First always returns the first item, irrespective of the lower bounds of the array.
var result = cells.First();
Depending on the need you can use each. Read the link below .
var firstValue = Yourlist.First(x => x.value);
or
var firstValue = Yourlist.FirstOrDefault(x => x.value);
or
var firstValue = Yourlist.Single(x => x.value);
or
var firstValue = Yourlist.SingleOrDefault(x => x.value);
LINQ Single vs First
If you are asking about Excel Interop:
Indexer - Indexer is 1-base:
cells[1,1].Value2 = "something";
IEnumerable - Using Cast and First or FirstOrDefalt:
cells.Cast<dynamic>().FirstOrDefault().Value2 = "something";
IEnumerable - Using GetEnumerator:
var enumerator = cells.GetEnumerator();
enumerator.MoveNext();
((dynamic)enumerator.Current).Value2 = "something";
If you are interested to know about the column index and row index in the sheet, the Column and Row property will show the coordinates in the sheet.
I'm learning c#, with my primary language before now being php. I was wondering how (or if) you could create an empty array in c#.
In php, you can create an array, and then add any number of entries to it.
$multiples=array();
$multiples[] = 1;
$multiples[] = 2;
$multiples[] = 3;
In c#, I'm having trouble doing something similar:
int[] arraynums = new int[];
arraynums[] = 1;
arraynums[] = 2;
arraynums[] = 3;
Which gives the error "array creation must have array size or array initializer." If I don't know how many entries I want to make, how do I do this? Is there a way around this?
If you don't know the size in advance, use a List<T> instead of an array. An array, in C#, is a fixed size, and you must specify the size when creating it.
var arrayNums = new List<int>();
arrayNums.Add(1);
arrayNums.Add(2);
Once you've added items, you can extract them by index, just like you would with an array:
int secondNumber = arrayNums[1];
c# arrays have a static size.
int[] arraynums = new int[3];
or
int[] arraynums = {1, 2, 3}
if you want to use dynamic sized array, you should use ArrayList, or List.
I would recommend using a different collection such as a List<T> or a Dictionary<TKey, TValue>. Calling the collection in PHP an array is just a misnomer. An array is a continuous fixed size block of memory that contains only a single type and offers direct access by calculating the offset for a given index. The data type in PHP does none of these things.
Examples;
List<int> my_ints = new List<int>();
my_ints.Add(500);
Dictionary<string, int> ids = new Dictionary<string, int>();
ids.Add("Evan", 1);
int evansId = ids["Evan"];
Examples of when to use an array;
string[] lines = File.ReadAllLines(myPath);
for (int i = 0; i < lines.Length; i++)
// i perform better than other collections here!
Newer way, since .NET 4.6 / Core 1.0, in case somebody hits this:
System.Array.Empty<T>() method.
This is more efficient if called multiple times, as it's backed by a single static readonly array generated at compile time.
https://learn.microsoft.com/en-us/dotnet/api/system.array.empty
https://referencesource.microsoft.com/#mscorlib/system/array.cs,3079
Try this post: Dynamic array in C#. It has a couple of links in the first answer that show alternate ways of indexing data. In C#, there is no way of making dynamic arrays but those links show some workarounds.
I'm trying to implement a paging algorithm for a dataset sortable via many criteria. Unfortunately, while some of those criteria can be implemented at the database level, some must be done at the app level (we have to integrate with another data source). We have a paging (actually infinite scroll) requirement and are looking for a way to minimize the pain of sorting the entire dataset at the app level with every paging call.
What is the best way to do a partial sort, only sorting the part of the list that absolutely needs to be sorted? Is there an equivalent to C++'s std::partial_sort function available in the .NET libraries? How should I go about solving this problem?
EDIT: Here's an example of what I'm going for:
Let's say I need to get elements 21-40 of a 1000 element set, according to some sorting criteria. In order to speed up the sort, and since I have to go through the whole dataset every time anyway (this is a web service over HTTP, which is stateless), I don't need the whole dataset ordered. I only need elements 21-40 to be correctly ordered. It is sufficient to create 3 partitions: Elements 1-20, unsorted (but all less than element 21); elements 21-40, sorted; and elements 41-1000, unsorted (but all greater than element 40).
OK. Here's what I would try based on what you said in reply to my comment.
I want to be able to say "4th through 6th" and get something like: 3,
2, 1 (unsorted, but all less than proper 4th element); 4, 5, 6 (sorted
and in the same place they would be for a sorted list); 8, 7, 9
(unsorted, but all greater than proper 6th element).
Lets add 10 to our list to make it easier: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1.
So, what you could do is use the quick select algorithm to find the the ith and kth elements. In your case above i is 4 and k is 6. That will of course return the values 4 and 6. That's going to take two passes through your list. So, so far the runtime is O(2n) = O(n). The next part is easy, of course. We have lower and upper bounds on the data we care about. All we need to do is make another pass through our list looking for any element that is between our upper and lower bounds. If we find such an element we throw it into a new List. Finally, we then sort our List which contains only the ith through kth elements that we care about.
So, I believe the total runtime ends up being O(N) + O((k-i)lg(k-i))
static void Main(string[] args) {
//create an array of 10 million items that are randomly ordered
var list = Enumerable.Range(1, 10000000).OrderBy(x => Guid.NewGuid()).ToList();
var sw = Stopwatch.StartNew();
var slowOrder = list.OrderBy(x => x).Skip(10).Take(10).ToList();
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
//Took ~8 seconds on my machine
sw.Restart();
var smallVal = Quickselect(list, 11);
var largeVal = Quickselect(list, 20);
var elements = list.Where(el => el >= smallVal && el <= largeVal).OrderBy(el => el);
Console.WriteLine(sw.ElapsedMilliseconds);
//Took ~1 second on my machine
}
public static T Quickselect<T>(IList<T> list , int k) where T : IComparable {
Random rand = new Random();
int r = rand.Next(0, list.Count);
T pivot = list[r];
List<T> smaller = new List<T>();
List<T> larger = new List<T>();
foreach (T element in list) {
var comparison = element.CompareTo(pivot);
if (comparison == -1) {
smaller.Add(element);
}
else if (comparison == 1) {
larger.Add(element);
}
}
if (k <= smaller.Count) {
return Quickselect(smaller, k);
}
else if (k > list.Count - larger.Count) {
return Quickselect(larger, k - (list.Count - larger.Count));
}
else {
return pivot;
}
}
You can use List<T>.Sort(int, int, IComparer<T>):
inputList.Sort(startIndex, count, Comparer<T>.Default);
Array.Sort() has an overload that accepts index and length arguments that lets you sort a subset of an array. The same exists for List.
You cannot sort an IEnumerable directly, of course.
I want to create a new array. Let's say
int[] clickNum = new int[800];
Then I want to do something like clickNum = 2, which would make all array elements starting from clickNum[0] to clickNum[800], set to 2. I know there's a way to do it by using a loop; but what I am after is just a function or a method to do it.
I suppose you could use Enumerable.Repeat when you initialise the array:
int[] clickNum = Enumerable.Repeat(2, 800).ToArray();
It will of course be slower, but unless you're going to be initiating literally millions of elements, it'll be fine.
A quick benchmark on my machine showed that initialising 1,000,000 elements using a for loop took 2ms, but using Enumerable.Repeat took 9ms.
This page suggests it could be up to 20x slower.
I don't think there's any built-in function to fill an existing array/list.
You could write a simple helper method for that if you need the operation in several places:
static void Fill<T>(IList<T> arrayOrList, T value)
{
for (int i = arrayOrList.Count - 1; i >= 0; i--)
{
arrayOrList[i] = value;
}
}
I guess you are looking for a function you created but you do not have the time to type it. So if you want it in a single line, try:
for(int i = 0; i < clickNum.Length; i++, clickNum[i] = 2);
Using Array.ConvertAll should be more efficient if you are working with very large arrays and performance is a concern:
int[] clickNum = Array.ConvertAll(new int[800], x => x = 2);
And you can also use a standard LINQ Select if performance doesn't worry you:
int[] clickNum = new int[800].Select(x => x = 2).ToArray();
Is there a function to remove the last cell from array?
it's a string array like: {"a","b","c",""}.
The length of an array is immutable, but you can create a new array without the empty "" strings:
string[] newArray = myArray.Where(str => str != "").ToArray();
Erm... just resize it
Array.Resize(ref theArray, theArray.Length -1);
From the docs
public static void Resize(ref T[] array, int newSize)
If it's an array of strings, you can do something like:
string[] results = theArray.Where(s => !string.IsNullOrWhitespace(s)).ToArray();
If you are just going to iterate the results, there's no need to convert back into an array, and you can leave off the .ToArray() at the end.
Edit:
If you just want to remove the last cell, and not empty entries (as suggested by your edited version), you can do this using Array.Copy more efficiently than using the LINQ statement above:
string[] results = new string[theArray.Length - 1];
Array.Copy( theArray, results, results.Length );
An array is a fixed-size collection object. That makes it woefully inadequate for what you want to do. The best you could do is create another one with one less element. That's expensive.
Fix the real problem, this should be a List<string>, now it's simple.
var newArraySize = oldArray.Length - 1;
var newArray = new string[newArraySize];
Array.Copy(oldArray, newArray, newArraySize);
Create new array equal to existing array size -1
aNewArray = aOldArray
Ofcourse you could just null the last element in your array, but that would result in problems later. Otherwise, use a nice flexible list.
If you always want to get rid of the last element,
int[] a = new[] {1, 2, 3, 4, 5};
int[] b = new int[a.Length - 1];
Array.Copy(a, b, a.Length - 1);