I have a Array
string[] names = { "Jim Rand", "Barry Williams", "Nicole Dyne", "Peter Levitt", "Jane Jones", "Cathy Hortings"};
Is there any way to find which is the shortest(Length wise) element in this array and then store rest of elements in a different array.
Thanks,
Ani
var orderedNames = names.OrderBy(name => name.Length);
string shortestName = orderedNames.First();
string[] otherNames = orderedNames.Skip(1).ToArray();
In C#, .Net 3.5:
string shortestName = names.Aggregate((n1, n2)=>n1.Length<n2.Length?n1:n2);
This is how you can store other elements in other array
var otherArrays = names.Exclude(new List<string>(){shortestName});
There is no .Exclude method (or extension method) for an Array and he didn’t say that he wanted to change the collection type for the new Array. Your use of the .Aggregate is outstanding so let’s take it one step further and use .Aggregate to do the excluding as well!
Like this:
string shortestName = names.Aggregate((n1, n2) => n1.Length < n2.Length ? n1 : n2);
string nonArrayString = names.Aggregate((n1, n2) => n2 != shortestName ? n1 + " " + n2 : n1);
string[] newNames = nonArrayString.Split(' ');
David Hedlund’s technique is still far better because it’s easier to read! There are no bonus points for writing the most complicated answer... lol
Related
I have a bunch of strings I would like to parse that all look like this:
"1001, 1003, 1005-1010"
"1015"
"900-903"
"200, 202-209, 211-220"
Sometimes these strings will be just one integer, sometimes multiple separated by commas, and sometimes a range, and the latter two can appear simultaneously in a single string in any order.
What I would like to do is create a function that takes in the string and returns a collection of integers by parsing the string. So for example the first string should return:
[1001, 1003, 1005, 1006, 1007, 1008, 1009, 1010]
What are some smart ways to do this in .NET 4.0?
.NET 4.0 means you got LINQ available, so you should probably use it:
var input = "1001, 1003, 1005-1010";
var results = (from x in input.Split(',')
let y = x.Split('-')
select y.Length == 1
? new[] { int.Parse(y[0]) }
: Enumerable.Range(int.Parse(y[0]), int.Parse(y[1]) - int.Parse(y[0]) + 1)
).SelectMany(x => x).ToList();
Traditional loop that might be easier to read:
string input = "1001, 1003, 1005-1010";
List<int> result = new List<int>();
foreach (string part in input.Split(','))
{
int i = part.IndexOf('-');
if (i == -1)
{
result.Add(int.Parse(part));
}
else
{
int min = int.Parse(part.Substring(0, i));
int max = int.Parse(part.Substring(i + 1));
result.AddRange(Enumerable.Range(min, max - min + 1));
}
}
I am trying to return a number that represents the similarity between two arrays.
I.e :
Array1: {Katy, Jenny, Sarah, Ben, Jill, Tina}
Array2: {Katy, John, Sam, Ben, Jill, Linda}
I want to return the number 3 because three comparisons are correct. Is this
possible? I can't think of any functions that will do this for me.
This is how you can count the amount of items that are equal in matching indices.
var c = arr1.Where((x, i) => x.Equals(arr2[i])).Count();
Note that you might want to assure that you don't try to access arr2 in an index that is out of range:
var c = arr1.Take(arr2.Length).Count(...);
If you don't care about index positions, you should use nemesv's solution.
There are many ways to do this. Since others have already specified a few ways, I will try to post a different way of doing the same.
If you consider matching based on index, you can do something like this using Zip
var cnt = 0;
Array1.Zip(Array2,(a,b)=>{
if(a.Equals(b)) ++cnt;
return string.Empty; //we dont need this
}).Count(); // use tolist or count to force evaluation
If you don't care about ordering and are just concerned about matching, you can use Intersect
Array1.Intersect(Array2).Count()
The way I would approach this problem is too take the value in the first array and compare it with every other value in the second array. If they match than increase a compare counter and that will tell you their are three comparisons that match.
This works for me:
var array1 = new string[] {"Katy", "Jenny", "Sarah", "Ben", "Jill", "Tina"};
var array2 = new string[] {"Katy", "John", "Sam", "Ben", "Jill", "Linda"};
var similarity = (array1.Length + array2.Length) - array1.Union(array2).Count();
Edit: Oh just saw you want them to be in the same position.
You're saying "According to index", assuming you mean that if "John" is on position 1 in the first list, and on position 2 on the second list => no match.
In that case:
int maxItems = Math.Min(arr1.Length, arr2.Length);
int matchCount = 0;
for(int i = 0; i < maxItems; i++)
{
if(object.Equals(arr1[i], arr2[i]))
matchCount++;
}
I'd do it like this:
int count = array1.Zip(array2, (a, b) => a.Equals(b)).Count(b => b);
The zip part returns an IEnumerable<bool> and the count part count how many times true occurs in that list.
I have a Array in c#.
public string[] alphabet = new string[] { "A","B","C",.......}
I want to return each and every elements which between two mentioned element.
Ex:
I want to return all elements in between "A" and "D". It should return {A,B,C,D} as result.
How can I do this? Is there any build in support or Are we suppose to write our own? Please help me.
Try GetRange():
alphabetList = alphabet.ToList();
string[] range = (alphabetList.GetRange(alphabetList.IndexOf("A"), alphabetList.IndexOf("D") + 1)).ToArray();
If its only about Alphabet array then we can call a loop and then cast its variable to char.
var fist = Array.IndexOf(alphabet, "A");
var second = Array.IndexOf(alphabet, "D");
var newArray = alphabet.Skip(fist).Take(second - fist + 1).ToArray();
OR
var newArray2 = alphabet.ToList().GetRange(fist, second - fist + 1).ToArray();
I do have a string like the following
"1 1/2 + 2 2/3"
Now i want the "1 1/2" as a variable, and the "2 2/3" as a different variable.
How do i fix this?
Thanks.
If you are always going to have a '+' inbetween, you could simply do:
var splitStrings = stringWithPlus.Split('+');
for (int i = 0; i < splitStrings.Length; i++) {
splitStrings[i] = splitStrings[i].Trim();
}
edit: If you really wanted to put these two parts into two separate variables, you could do so. But it's quite unnecessary. The type of the var is going to be string[] but to get them into two variables:
var splitStrings = stringWithPlus.Split('+');
for (int i = 0; i < splitStrings.Length; i++) {
splitStrings[i] = splitStrings[i].Trim();
}
string firstHalf = splitStrings[0];
string secondHalf = splitStrings[1];
It would be better though, to just access these strings via the array, as then you're not allocating any more memory for the same data.
If you are comfortable with Linq and want to shorten this (the above example illustrates exactly what happens) you can do the split & foreach in one line:
var splitStrings = stringWithPlus.Split('+').Select(aString => aString.Trim()).ToArray();
string firstHalf=splitStrings[0];
string secondHalf=splitStrings[1];
If this syntax is confusing, you should do some searches on Linq, and more specifically Linq to Objects.
To make it shorter I used Linq to Trim the strings. Then I converted it back to an array.
string[] parts = stringWithPlus.Split('+').Select(p => p.Trim()).ToArray();
Use them as:
parts[0], parts[1]... parts[n - 1]
where n = parts.Length.
I have a string coming in the format:
div, v6571, 0, div, v8173, 300, p, v1832, 400
I want to split this string into multiple arrays, for the example above I would need 3 arrays, such that the format would be like this:
item[0] -> div
item[1] -> v6571
item[2] -> 0
I know that I can just do a .Split(',') on the string and put it into an array, but that's one big array. For the string example above I would need 3 arrays with the structure provided above. Just getting a bit confused on the iteration over the string!
Thanks!
I'm not sure exactly what you're looking for, but to turn the above into three separate arrays, I'd do something like:
var primeArray = yourString.Split(,);
List<string[]> arrays = new List<string[]>();
for(int i = 0; i < primeArray.Length; i += 3)
{
var first = primeArray[i];
var second = primeArray[i+1];
var third = primeArray[i+2];
arrays.Add(new string[] {first, second, third});
}
Then you can iterate through your list of string arrays and do whatever.
This does assume that all of your string arrays will always be three strings long- if not, you'll need to do a foreach on that primeArray and marshal your arrays more manually.
Here's the exact code I used. Note that it doesn't really change anything from my original non-compiled version:
var stringToSplit = "div, v6571, 0, div, v8173, 300, p, v1832, 400";
List<string[]> arrays = new List<string[]>();
var primeArray = stringToSplit.Split(',');
for (int i = 0; i < primeArray.Length; i += 3)
{
var first = primeArray[i];
var second = primeArray[i + 1];
var third = primeArray[i + 2];
arrays.Add(new string[] { first, second, third });
}
When I check this in debug, it does have all three expected arrays.
.Split(",") is your best bet. You can then modify that string array to reflect whatever structure you need.
You could use Regular Expressions or other methods, but nothing will have the performance of String.Split for this usage case.
The following assumes that your array's length is a multiple of three:
var values = str.Split(',')
string[,] result = new string[values .Length / 3, 3];
for(int i = 0; i < params.Length; i += 3)
{
int rowIndex = i / 3;
result[rowIndex, 0] = values [i];
result[rowIndex, 1] = values [i + 1];
result[rowIndex, 2] = values [i + 2];
}
Compiled in my head, but it should work.
Just so that I'm understanding you right, you need to sort them into:
1) character only array
2) character and number
3) numbers only
If so, you can do the following:
1) First try to parse the string with Int32.Parse
if successful store in the numbers array
2) Catch the exception and do a regex for the numbers
to sort into the remainder 2 arrays
Hope it helps (: Cheers!