tags:

views:

80

answers:

6

I have the following strings in a text file "test"

Table Name.type
Market Drinks.tea

I wana split the strings so that I get the following output

ObjectName = Table    AttributeName = Name    Attribute Type =type
ObjectName = Market   AttributeName = Drinks  Attribute Type =tea

here is my code

            string[] lines = File.ReadAllLines(@"d:\test.txt");
            int i = 0;
            var items = from line in lines
                        where i++ != 0
                        select new{
                            objectName = line.Split(new char[] {' '})[0],
                            attrName = line.Split(new char[]{'.'})[1],
                            attrType = line.Split(new char[] { ' ' })[2]
                        };
            foreach (var item in items)
            {
                Console.WriteLine("ObjectName = {0}, AttributeName = {1}, Attribute Type = {2}",
                    item.objectName, item.attrName, item.attrType);
            }

I'm getting an out of boundaries exception.

PS: there are no spaces at the end of the strings in the text file I just wanted to test a character!

+1  A: 

On the splitting part, you should do it like this (provided you are sure your input is in the correct format):

attrName = line.Split(' ')[1].Split('.')[0],
attrType = line.Split(' ')[1].Split('.')[1]
Dan Dumitru
this didn't give the desired output though it helped me solve the problem. I'll write the solution in Answers
Reda
@Reda - Are you sure? I even tested this on your input examples.
Dan Dumitru
it works I jut forgot to remove the char[]
Reda
+1  A: 

The out of bounds is on this line - attrType = line.Split(new char[] { ' ' })[2]

your attrType should be = line.Split(new char[] { '.' } )[1];

attrName should be = line.Split(new char[] {' '})[1].Split(new char[] {'.'})[0]

As Henk Holterman has said, you dont need to use new char[] inside split so your lines would be -

attrType = line.Split('.')[1];
attrName = line.Split(' ')[1].Split('.')[0];
Sachin Shanbhag
this doesn't give the desired output though
Reda
@Reda - you mean without using new char[] ?
Sachin Shanbhag
ah ok thx alot for the answer it works fine now
Reda
+3  A: 

You don't need the new char[] { ... } surrounding because String.Split() uses params

To fix the index-out-of-bounds, the last part of the select should become:

        attrType = line.Split(' ', '.' )[2]

Edit

And thanks to @Kobi, a let will let you do the Split just once, a great improvement when you have many rows and/or columns.

var items = from line in lines
            where i++ != 0
            let words = line.Split(' ', '.')
            select new
            {
                objectName = words[0],
                attrName = words[1],
                attrType = words[2]
            };

Old answer

You can use the same Split for all 3 parts, making it a little easier to read:

       select new{
             objectName = line.Split(' ', '.' )[0],
             attrName   = line.Split(' ', '.' )[1],
             attrType   = line.Split(' ', '.' )[2]
        };
Henk Holterman
thx this works as well
Reda
It is also possible to use `let words = line.Split(' ', '.')`, followed by `objectName = words[0]`.
Kobi
+2  A: 

Use regular expressions which is more robust:

        static void Main()
    {

        const string PATTERN = @"^([\w]+)\s+([\w]+)\.(\w+)";
        const string TEXT = "Table Name.type\r\nMarket Drinks.tea";

        foreach (Match match in Regex.Matches(TEXT, PATTERN, RegexOptions.Multiline))
        {
            Console.WriteLine("ObjectName = {0}   AttributeName = {1}  Attribute Type ={2}",
                match.Groups[1].Value, match.Groups[2].Value, match.Groups[3].Value);
        }

    }

Outputs:

ObjectName = Table   AttributeName = Name  Attribute Type =type
ObjectName = Market   AttributeName = Drinks  Attribute Type =tea
Aliostad
A: 

thx to the replies here is the right answer for the desired output

objectName = line.Split(' ')[0],
attrName = line.Split(' ')[1].Split('.')[0],
attrType = line.Split('.')[1]
Reda
A: 

if you want to do in this way just use Regex its more flexible

const string pattern = @"(?<objectName>\w+)\s(?<attrName>\w+)\.(?<attrType>\w+)";

string[] lines = File.ReadAllLines(@"e:\a.txt");
var items = from line in lines
            select new
            {
                objectName = Regex.Match(line, pattern).Groups["objectName"].Value,
                attrName = Regex.Match(line, pattern).Groups["attrName"].Value,
                attrType = Regex.Match(line, pattern).Groups["attrType"].Value
            };

foreach (var item in items.ToList())
{
    Console.WriteLine("ObjectName = {0}, AttributeName = {1}, Attribute Type = {2}",
        item.objectName, item.attrName, item.attrType);
}
Sebastian Brózda