Change value of each element by linq - c#

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

Related

Determine if array contains all zeroes

I create the following array like this:
array<UInt16>^ temp = gcnew array<UInt16>(1000);
How do I determine if this entire array has been filled with zero or not.
I think I may be able to use TrueForAll(T) but I'm not sure.
var allElementsAreZero = temp.All(o => o == 0);
Simple as that.
It'll return when it finds one that doesn't satisfy the condition, so may not necessarily iterate through your whole collection:
"The enumeration of source is stopped as soon as the result can be determined."
https://msdn.microsoft.com/en-us/library/bb548541(v=vs.110).aspx
This should work properly (here I used LINQ):
IEnumerable<int> values = new List<int>(); // Or use any array type instead of List.
... Add your values here ...
var allAreZero = !values.Any(v => v != 0);
P.S. the array class inherits IEnumerable.
And here is a solution with foreach:
var isAllZero = true;
foreach (var value in values)
{
if (value != 0)
{
isAllZero = false;
break;
}
}
UPDATE
The really difference between TrueForAll, and my LINQ code is: LINQ code uses the fluent (or maybe also query) syntax, where TrueForAll is just a normal function where you send the array as a parameter.
initialize a counter from 0 then use for loop to interate through the array and increment the counter whenever it finds 0, and at the end compare the counter with size of array if its equal, it has all zeros
Reading the C++/CLI specification, it has been filled with
0s because you created it with a "new-expression" and the default value of the element type is 0.
24.2 CLI array creation
CLI array instances are created by new-expressions containing gcnew (§15.4.6) or …
Elements of CLI arrays created by new-expressions are always initialized to their default value.

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

Cannot implicitily convert type `double[]` to `System.Collections.Generic.List<double>`

I am getting the following error message with the code below. I thought the data type List<double> was the same as double[] but that C# required it to be instantiated using the first syntax for the variable to work as an object. What am I doing wrong or is my thinking wrong?
Cannot implicitily convert type `double[]` to `System.Collections.Generic.List<double>`
Code:
private void RunScript(List<Curve> crv, double nb, ref object DivPts)
{
List<double> nbtemp = new List<double>();
List<double> Divpt = new List<double>();
for(int i = 0; i < crv.Count;i = i + 2)
{
nbtemp = crv[i].DivideByLength(nb, true);
}
Divpt = nbtemp;
No, a list is not an array, even though the concepts are somewhat similar. The List<T> class in C# is actually implemented with a behind-the-scenes array.
If you want to set a List from an array, you can use something like this:
nbtemp = new List<double>(crv[i].DivideByLength(nb, true));
that will create a new List, and initialize it with the array. You can also use the AddRange method of the List, if you would like to append an array to an existing list, like this:
nbtemp.AddRange(crv[i].DivideByLength(nb, true));
You can't convert from Array to List, but you can easily call:
nbtemp = crv[i].DivideByLength(nb, true).ToList();
Or, since you already have to Lists defined, you could also:
nbtemp.AddRange(crv[i].DivideByLength(nb, true));
You are using an assignment and it is hard to tell what DivideByLength returns, if a single value then use:
nbtemp.Add(crv[i].DivideByLength(nb, true));
Otherwise, if it is returning an array, try changing your definition to allow the list to contain arrays:
List<double[]> nbtemp = new List<double[]>();
Note that List is not equivalent to double[]. List has many features that a simple array does not. You can see the differences by looking at the two different MSDN articles for which methods are publicly exposed.
List
Array
Also, your for loop as it stands is using an assignment. Without a change to that part of the code, you will only assign the last iteration of the for loop to the variable nbtemp (assuming you remove the error)
They are both IEnumerable implementers but they are not equivalent types. You will need to perform a cast or a method call. In the code above I would say you'd need:
nbtemp = (crv[i].DivideByLength(nb, true)).ToList();
or
nbtemp.AddRange(crv[i].DivideByLength(nb, true));

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.

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