Array.Sort() into a new array? - c#

I'm using Array.Sort() to sort an array of doubles into ascending order. And then in some cases I do a Reverse() to change the order. But ideally I'd like to preserve my original array. Does C# have a simple, native sort for arrays that outputs to a new array rather than sorting the existing array in-place?

You can use LINQ to do that:
var result = source.OrderBy(x => x).ToArray();
or for descending order:
var result = source.OrderByDescending(x => x).ToArray();
or you can create new array first and than sort it:
var newArray = (double[])source.Clone();
newArray.Sort();
I would expect the latter to be faster, but you should probably measure it to be sure.

Related

Change value of each element by linq

Is it possible to do sth like this in LINQ:
int[] d = new int[c.Length + 1];
int e = 1;
d.ToList().ForEach(r =>
{
r = e;
e++;
});
?.
When I did this, it returned me sequence of zeros.
Regards.
Yes, it would, for two reasons:
You're creating a copy of the original array as a List<int>, and then trying to modify the List<int>. That wouldn't modify the array.
Your lambda expression changes the value of the parameter, that's all. It doesn't modify the list.
Basically, LINQ is for querying. Don't even bother trying to do this: use a for loop if you want to modify the collection.
However, if your aim is to produce an array of 1...(c.Length+1), just use Enumerable.Range:
var array = Enumerable.Range(1, c.Length + 1).ToArray();

Sort Array by contains specific char count

I have an array and I want to sort this array by its element' specific character count.
var myNewArray = myArray.ToList().Sort(u => u.Name.Split(' ').Length);
but this does not work at all.
How can I provide the LINQ code for this problem ?
myArray[0] = "word1 word2"
myArray[1] = "word1"
myArray[2] = "word3 word2 word2 word2"
when Apply sort my array element order must be like
myArray[2],myArray[0],myArray[1]
Use:
var myNewArray = myArray.OrderByDescending(u => u.Name.Split(' ').Length).ToList();
To count the number of words
User OrderByDescending instead
var myNewArray = myArray.OrderByDescending(u => u.Name.Split(' ').Length).ToList();
This will save you producing two in-memory lists as well
Your code will not compile List.Sort modifies the current list in place, it doesn't return a new collection.
Having said that, you need Enumerable.OrderByDescending
sentence which have more words must be top of the array
Since you have an Array to begin with you can simply do:
var myNewArray = myArray.OrderByDescending(u => u.Name.Split(' ').Length).ToArray();
Make sure to include using System.Linq;
(Remove ToArray if you only need an IEnumerable<T>)

How do I sort 2 lists by the same criteria?

public void sort()
{
datelist = new List<DateTime>(rdate); //timedates
intlist = new List <Int>(rint); //integers
datelist.Sort((a, b) => a.CompareTo(b)); //sorts the dates ascending(I think)
}
I have two initial arrays; these match by index number. I have converted these to lists in order to sort them. How would I sort intlist in exactly the same way as the datelist? Thanks.
Assuming you have linq at your disposal (.net 3.5 +) you can do the following.
// Define your collections
var dates = new[]
{
new DateTime(2012, 1, 1), new DateTime(2012, 1, 2), new DateTime(2012, 1, 5),
new DateTime(2012, 1, 3)
};
var ints = new[] {1,2,4,3};
var result = dates
.Select((d, i) => new {Date = d, Int = ints[i]}) // This joins the arrays based on index
.OrderBy(o => o.Date) // Sort by whatever field you want
.ToArray(); // Return the results an array
// Extract just the dates
dates = result.Select(o => o.Date).ToArray();
// Extract just the ints
ints = result.Select(o => o.Int).ToArray();
Don't create lists; use one of the static Array.Sort overloads that takes two array parameters. The method sorts both arrays in the order specified by the values in the "keys" array, using either the default comparer or a comparer that you provide.
EDIT
In revisiting this answer because of a recent upvote (thank you, upvoter!), I would like to underscore that the Array.Sort solution uses far less code and far less memory overhead/garbage collection pressure:
public void sort()
{
Array.Sort(rint, rdate); //sorts both arrays in the order dictated by the ints
}
OR
public void sort()
{
Array.Sort(rdate, rint); //sorts both arrays in the order dictated by the dates
}
In SynXsiS's code, you're allocating a new anonymous object for each date/int pair, as well as another array to hold them(private to the OrderedEnumerable returned by the OrderBy call), plus another array to hold them (the ToArray call, which could probably be omitted), and then you're iterating that array twice to create two more arrays.
If these performance considerations aren't important (and mostly likely they aren't), I would still choose the Array.Sort solution on the grounds of shorter code.
As a final thought, SynXsiS's solution would benefit from Enumerable.Zip:
result = dates.Zip(ints, (d, i) => new { Date = d, Int = i }).OrderBy(o => o.Date);
dates = result.Select(o => o.Date).ToArray();
ints = result.Select(o => o.Int).ToArray();

Parse int[] from "1,2,3"

I have a multiselect dropdown called ID that submits ID=1,2,3 which I need parsed into an integer array to do a Contains() on in a filter method. At the moment I use:
string[] ids = Request["ID"].Split(',');
Which I don't really like because its slower to compare string than int. Any suggestions?
Request["ID"].Split(',').Select(x=>int.Parse(x)).ToArray();
Of course, this will throw if any of the resulting numeric strings are not "parseable" (does such a word exist?).
It depends on how many times you will look up in the array if converting to ints are faster or the string comparison is faster.
HashSet<int> ids = new HashSet<int>(from s in Request["ID"].Split(',')
select int.Parse(s));
But probably the fastest if you have many id:s will be to create a HashSet<string>:
HashSet<string> = new HashSet<string>(string[] ids = Request["ID"].Split(','));
int[] ids = Request["ID"].Split(',').Select(Convert.ToInt32).ToArray();
First:
string[] arr = Request["ID"].Split(',')
Then:
Array.ConvertAll(arr, s => Int32.Parse(s));
Array.ConvertAll(arr, Int32.Parse);
arr.Select(s => Int32.Parse(s));
arr.Select(Int32.Parse);
Then:
new HashSet<int>(result);
(the most fast container to perform Contains())
See also:
Convert string[] to int[] in one string of code using LINQ
Which one is faster in processing and conversion int.Parse(), int.TryParse(), Convert.Int32()
If you don't have linq, you can:
string[] ids = Request["ID"].Split(',');
int[] items = new int[ids.Length];
for(int i = 0; i<ids.Length; i++)
{
items[i] = int.Parse(ids[i]);
}

Convert List of longs to string array

What is the best way to convert a List of primitive longs to an array of strings?
I think I'm looking for something fancier than writing my own loop, etc..
This should do the trick:
string[] arr = list.Select(l => l.ToString()).ToArray();
This is worth checking against the performance of a select statement.
string[] result = Array.ConvertAll(list.ToArray(), i => i.ToString());

Categories

Resources