C# Exclude Array Object - c#

I have a slight problem with this code:
string[] sWords = {"Word 1", "Word2"}
foreach (string sWord in sWords)
{
Console.WriteLine(sWord);
}
This works fine if I want every object to print.
I was wondering if I could exclude the first item in the array?
So it would only output "Word 2". I know the obvious solution is not to include the first item but in this case I can't.

Using LINQ to Objects, you can just use Skip:
foreach (string word in words.Skip(1))
{
Console.WriteLine(word);
}

Using LINQ in .Net 3.5 and up:
string[] words = {"Word 1", "Word2"}
foreach (string word in words.Skip(1))
{
Console.WriteLine(word);
}
Note that you must have a using System.Linq; statement at the top of your file, as Skip is an extension method.
An alternative option is to use a regular for loop:
for( int x = 1; x < words.Length; ++x )
Console.WriteLine(words[x]);
I also strongly discourage the use of Hungarian-like prefixes in variable names in .Net.

You can use a for loop instead:
string[] sWords = {"Word 1", "Word2"};
var len = sWords.Length;
for (int i = 1; i < len; i++)
{
Console.WriteLine(sWords[i]);
}

You could do
string[] sWords = {"Word 1", "Word2"};
for(int i=1; i<sWords.Length; i++)
{
Console.WriteLine(sWord[i]);
}

Related

Filling a character array with characters from a string

I'm trying to fill an array with characters from a string inputted via console. I've tried the code bellow but it doesnt seem to work. I get Index out Of Range exception in the for loop part, and i didn't understand why it occured. Is the for loop range incorrect? Any insight would be greatly appreciated
Console.WriteLine("Enter a string: ");
var name = Console.ReadLine();
var intoarray = new char[name.Length];
for (var i = 0; i <= intoarray.Length; i++)
{
intoarray[i] = name[i];
}
foreach (var n in intoarray)
Console.WriteLine(intoarray[n]);
using ToCharArray() strings can be converted into character arrays.
Console.WriteLine("Enter a string: ");
var name = Console.ReadLine();
var intoarray= name.ToCharArray();
foreach (var n in intoarray)
Console.WriteLine(n);
if you are using foreach, you should wait for the index to behave as if you were taking the value.
Console.WriteLine(n);
Since arrays start at 0 and you are counting inclusive of length, the last iteration will exceed the bounds.
Just update the loop conditional to be less than length rather than less than or equal to..
I like snn bm's answer, but to answer you question directly, you're exceeding the length of the input by one. It should be:
for (var i = 0; i <= intoarray.Length - 1; i++)
(Since strings are zero-indexed, the last character in the underlying array is always going to be in the position of arrayLength - 1.)
1: the iteration should be for (var i = 0; i < intoarray.Length; i++)
2: the code
foreach (var n in intoarray)
Console.WriteLine(intoarray[n]);
also throws an exception, for "n" is a character in the array while it's used as array index.
3: In addition there's a much easier way to convert string to char array
var intoarray = name.ToCharArray();
Here's the result
Here is your mistake. There are so many options to represent i < intoarray.Length.
for (var i = 0; i < intoarray.Length; i++) // original was i <= intoarray.Length in your code
{
intoarray[i] = name[i];
}
With linq:
// Select all chars
IEnumerable<char> intoarray =
from ch in name
select ch; // can use var instead of IEnumerable<char>
// Execute the query
foreach (char temp in intoarray)
Console.WriteLine(temp);

C# Reverse() function not working properly

I'm really confused why the reverse function isn't working properly..
I currently have
List<string> decimalVector = new List<string>();
string tempString = "10"
//For Vector Representation
for (int i = 0; i < tempString.Length; i++)
{
//As long as we aren't at the last digit...
if (i != (tempString.Length-1))
{
decimalVector.Add(tempString[i].ToString() + ",");
}
else
{
decimalVector.Add(tempString[i].ToString());
}
}
Console.Write("Decimal: " + decimalOutput);
Console.Write(" Vector Representation: [");
decimalVector.Reverse();
for (int i = 0; i < decimalVector.Count; i++)
{
Console.Write(decimalVector[i]);
}
Console.Write("]");
For some reason instead of the code outputting [0,1] as it should - since that is the reverse of what is currently in the decimalVector ([1,0]) ..It prints out [01,] I am so confused. Why is it randomly moving my comma out of place? Am I doing something really stupid and not seeing it?
You're reversing the order of the elements, not the order of the characters. It's 1, followed by 0. When reversed it's 0 followed by 1,. When you print that, you get 01,.
You should not include the separating , as part of the list elements, but rather only add it when printing.
Btw there is the string.Join method, which solves your problem elegantly:
string.join(",", tempString.Select(c => c.ToString()).Reverse())
Try this:
foreach (string s in decimalVector.Reverse())
{
Console.Write(s);
}

SynonymInfo[] For Microsoft.Office.Interop.Word in C#

In C# i using
using word = Microsoft.Office.Interop.Word;
For get a Synonym for words by using this code
var app = new word.Application();
var infosyn = app.SynonymInfo[Wtext[Op + 1].ToString(), word.WdLanguageID.wdArabic];
foreach (var item in infosyn.MeaningList as Array)
{
listBox1.Items.Add(item.ToString());
}
Image here
My Issue is i got only the meaning list ( What is red boxes in image), but i want all words like in the image ( words in red boxes and blue arrows, The whole list).
Note: i use Meaninglist, RelatedWordList and it's not working and make loops in loop take a each synonym words and check their synonyms. Like This
var apps = new words.Application();
var infosyns = apps.SynonymInfo[item.ToString(), words.WdLanguageID.wdArabic] ;
foreach (var iitem in infosyns.MeaningList as Array)
{
listBox1.Items.Add(iitem.ToString());
var appss = new wordss.Application();
var infosynss = appss.SynonymInfo[iitem.ToString(),wordss.WdLanguageID.wdArabic] ;
foreach (var iiitem in infosyns.MeaningList as Array)
{
listBox1.Items.Add(iiitem.ToString());
}
}
Image here
Oli4 is correct.
You need to loop through the underlying data by doing something like this:
foreach (var iiitem in infosyns.MeaningList as Array)
{
listBox1.Items.Add(iiitem.ToString());
foreach (var item in iiitem.MeaningList)
{
listBox1.Items.Add(item.ToString());
}
}
I had a similar problem, however by looping a predefined amount of times through the results, I got a lot more. This was just a quick code and I believe the efficiency could be improved, However I believe it will get you on the right track. (It is somewhat similar to what you have done.
private static string[] getAllMeanings(Application wordApp, string word, int maxSize = 12,bool addOriginal = false)
{
List<string> stringArr = new List<string>();
if (addOriginal)stringArr.Add(word);
SynonymInfo theSynonyms = wordApp.SynonymInfo[word];
foreach (var Meaning in theSynonyms.MeaningList as Array)
{
if (stringArr.Contains(Meaning) == false) stringArr.Add((string)Meaning);
}
for (int ii = 0; ii < stringArr.Count; ii++)
{
theSynonyms = wordApp.SynonymInfo[stringArr[ii]];
foreach (string Meaning in theSynonyms.MeaningList as Array)
{
if (stringArr.Contains(Meaning)) continue;
stringArr.Add(Meaning);
}
if (stringArr.Count >= maxSize) return stringArr.ToArray();
}
return stringArr.ToArray();
}
Basically this function gets all the related words and then recursively adds the related word and finds their related words. This ends up by very closely resembling your result if you set the maxSize to 15;
Note: maxSize is to stop the function, for instance the word "have" has at least 3600 'synonyms'. And optimally your result should remain relevant.

Iterate two Arrays with ForEach statement in C# [duplicate]

This question already has answers here:
Iterate two Lists or Arrays with one ForEach statement in C#
(12 answers)
Closed 8 years ago.
I have 2 array
string[] Namesvalues = Names.Split(',');
string[] TotalValues = Total.Split(',');
Above both arrays have exactly equal values.what i want to do is to iterate above two arrays in parallel and want to get one by one value from both arrays.
Can any one tell me how can i do that??
You could simply use a for-loop:
for(int i = 0; i < NamesValues.Length; i++)
{
string name = NamesValues[i];
string totalValue = TotalValues[i];
}
If the length is different you could use ElementAtOrDefault:
for(int i = 0; i < Math.Max(NamesValues.Length, TotalValues.Length) ; i++)
{
string name = NamesValues.ElementAtOrDefault(i);
string totalValue = TotalValues.ElementAtOrDefault(i);
}
You also could use Enumerable.Zip to create an anonymous type with both values:
var namesAndValues = NamesValues.Zip(TotalValues,
(n, tv) => new { Name = n, TotalValue = tv });
foreach(var nv in namesAndValues)
{
Console.WriteLine("Name: {0} Value: {1}", nv.Name + nv.TotalValue);
}
Note that the second approach using a for-loop and ElementAtOrDefault is different to to the Enumerable.Zip approach.
The former iterates both arrays completely and ElementAtOrDefault returns null for the value of the smaller array if there is no element at that index.
The latter Zip combines elements only until it reaches the end of one of the sequences.
So when you use Math.Min instead of Math.Max in the for-loop you get a similar behaviour, but then you should use the first approach anyway since there's no need for ElementAtOrDefault.
//exactly equal length
for (int i = 0; i < Namesvalues.Length; i++)
{
var name = Namesvalues[i];
var total = TotalValues[i];
}

Optimizing counting characters within a string

I just created a simple method to count occurences of each character within a string, without taking caps into account.
static List<int> charactercount(string input)
{
char[] characters = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
input = input.ToLower();
List<int> counts = new List<int>();
foreach (char c in characters)
{
int count = 0;
foreach (char c2 in input) if (c2 == c)
{
count++;
}
counts.Add(count);
}
return counts;
}
Is there a cleaner way to do this (i.e. without creating a character array to hold every character in the alphabet) that would also take into account numbers, other characters, caps, etc?
Conceptually, I would prefer to return a Dictionary<string,int> of counts. I'll assume that it's ok to know by omission rather than an explicit count of 0 that a character occurs zero times, you can do it via LINQ. #Oded's given you a good start on how to do that. All you would need to do is replace the Select() with ToDictionary( k => k.Key, v => v.Count() ). See my comment on his answer about doing the case insensitive grouping. Note: you should decide if you care about cultural differences in characters or not and adjust the ToLower method accordingly.
You can also do this without LINQ;
public static Dictionary<string,int> CountCharacters(string input)
{
var counts = new Dictionary<char,int>(StringComparer.OrdinalIgnoreCase);
foreach (var c in input)
{
int count = 0;
if (counts.ContainsKey(c))
{
count = counts[c];
}
counts[c] = counts + 1;
}
return counts;
}
Note if you wanted a Dictionary<char,int>, you could easily do that by creating a case invariant character comparer and using that as the IEqualityComparer<T> for a dictionary of the required type. I've used string for simplicity in the example.
Again, adjust the type of the comparer to be consistent with how you want to handle culture.
Using GroupBy and Select:
aString.GroupBy(c => c).Select(g => new { Character = g.Key, Num = g.Count() })
The returned anonymous type list will contain each character and the number of times it appears in the string.
You can then filter it in any way you wish, using the static methods defined on Char.
Your code is kind of slow because you are looping through the range a-z instead of just looping through the input.
If you only need to count letters (like your code suggests), the fastest way to do it would be:
int[] CountCharacters(string text)
{
var counts = new int[26];
for (var i = 0; i < text.Length; i++)
{
var charIndex - text[index] - (int)'a';
counts[charIndex] = counts[charindex] + 1;
}
return counts;
}
Note that you need to add some thing like verify the character is in the range, and convert it to lowercase when needed, or this code might throw exceptions. I'll leave those for you to add. :)
Based on +Ran's answer to avoiding IndexOutOfRangeException:
static readonly int differ = 'a';
int[] CountCharacters(string text) {
text = text.ToLower();
var counts = new int[26];
for (var i = 0; i < text.Length; i++) {
var charIndex = text[i] - differ;
// to counting chars between 'a' and 'z' we have to do this:
if(charIndex >= 0 && charIndex < 26)
counts[charIndex] += 1;
}
return counts;
}
Actually using Dictionary and/or LINQ is not optimized enough as counting chars and working with a low level array.

Categories