Sort Array by contains specific char count - c#

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>)

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();

Array.Sort() into a new array?

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.

Sorting a MatchCollection in C#

I am trying to rewrite TCL code in C#. The code of concern is the following:
set list [regexp -all -inline -line {.+\d+.+\d+} $string]
In this case the regexp procedure returns a list of all matches in the string after which I am sorting this list of strings with another expression based on a numeric value in the end of the string:
set sortedList [lsort -decreasing -integer -index end $list]
The question is, how to achieve the same in C#? I tried the following:
MatchCollection mc = Regex.Matches(inputString, regexPattern, RegexOptions.Multiline);
As I found however, I cannot sort a matchcollection directly in C# so I copied every match to an array:
string[] arrayOfMatches = new string[mc.Count];
for (int i = 0; i < mc.Count; i++)
{
arrayOfMatches[i] = mc[i].Groups[1].Value;
}
However, when I try to sort the arrayOfMatches array, I do not see the Sort method available. What am I missing and am I moving in the right direction? Thanks!
To sort arrays, you use the static Array.Sort() method. That said, to sort the matches you would need to define an IComparer. Perhaps an easier way to do this would be to use a little linq-fu:
var mc = Regex.Matches(input, patter);
var matches = new Match[mc.Count];
mc.CopyTo(matches, 0);
var sorted = matches
.Select(x => x.Groups[1].Value)
.OrderBy(x => x);
Sorted will be the value of 2nd item the groups array sorted in ascending order. How it works is the .Select creates the projection you want and the .OrderBy sorts the stack.
The Array.Sort() method is static, so you have to call it like this:
Array.Sort(arrayOfMatches, comparison);
Where comparison is either a delegate that can compare two strings or an implementation of IComparer<T> that can do the same.
But it might be easier to use LINQ:
var matches =
from Match m in mc
let value = m.Groups[1].Value
let numericValue = int.Parse(value)
orderby numericValue descending
select value;
This assumes the whole value is the number. If I understand you correctly and you want to get a numeric value from the end of the string, you would have to add code to do that.

Split and select specific elements

I have a comma separated string which specifies the indexes. Then I have one more comma separated string which has all the values.
EX:
string strIndexes = "5,6,8,15";
string strData = "ab*bc*dd*ff*aa*ss*ee*mm*jj*ii*waa*jo*us*ue*ed*ws*ra";
Is there a way to split the string strData and select only the elements which are at index 5, 6, 8 or 15. Or will I have to split the string first then loop through the array/list and then build one more array/list with the values at indexes defined by string strIndexes (i.e. 5, 6,7,15 in this example)
Thanks
It's reasonably simple:
var allValues = strData.Split('*')
var selected = strIndexes.Split(',')
.Select(x => int.Parse(x))
.Select(index => allValues[index]);
You can create a list from that (by calling selected.ToList()) or you can just iterate over it.
It depends a bit on the length of the string. If it is relatively short (and therefore any array from "Split" is small) then just use the simplest approach that works; Split on "*" and pick the elements you need. If it is significantly large, then maybe something like an iterator block to avoid having to create a large array (but then... since the string is already large maybe this isn't a huge overhead). LINQ isn't necessarily your best approach here...
string[] data = strData.Split('*');
string[] result = Array.ConvertAll(strIndexes.Split(','),
key => data[int.Parse(key)]);
which gives ["ss","ee","jj","ws"].
call Split(','); on the first string and you get an array of strings, that array you can access by index and the same you can do on the second array. No need to loop array lists.

How to Compare Values in Array

If you have a string of "1,2,3,1,5,7" you can put this in an array or hash table or whatever is deemed best.
How do you determine that all value are the same? In the above example it would fail but if you had "1,1,1" that would be true.
This can be done nicely using lambda expressions.
For an array, named arr:
var allSame = Array.TrueForAll(arr, x => x == arr[0]);
For an list (List<T>), named lst:
var allSame = lst.TrueForAll(x => x == lst[0]);
And for an iterable (IEnumerable<T>), named col:
var first = col.First();
var allSame = col.All(x => x == first);
Note that these methods don't handle empty arrays/lists/iterables however. Such support would be trivial to add however.
Iterate through each value, store the first value in a variable and compare the rest of the array to that variable. The instant one fails, you know all the values are not the same.
How about something like...
string numArray = "1,1,1,1,1";
return numArrray.Split( ',' ).Distinct().Count() <= 1;
I think using List<T>.TrueForAll would be a slick approach.
http://msdn.microsoft.com/en-us/library/kdxe4x4w.aspx
Not as efficient as a simple loop (as it always processes all items even if the result could be determined sooner), but:
if (new HashSet<string>(numbers.Split(',')).Count == 1) ...

Categories

Resources