tags:

views:

108

answers:

5

How can i programatically push an array of strings into generic Stack ?

string array

 string[] array=new string[]{"Liza","Ana","Sandra","Diya"};

Stack Setup

 public class stack<T>
 {
    private int index;

    List<T> list; 

    public stack()
    {
        list = new List<T>();
        index=-1;

    }

    public void Push(T obj)
    {

        list.Add(obj);
        index++;
    }
 ...........
}

What is the change do i need here ?

stack<string> slist = new stack<string>();
var v = from vals in array select (p => slist.Push(p));

Error Report :

The type of the expression in the select clause is incorrect.
+10  A: 

LINQ is a query language/framework. What you want to perform here is a modification to a collection object rather than a query (selection) - this is certainly not what LINQ is designed for (or even capable of).

What you might like to do, however, is to define an extension method that for the Stack<T> class, however. Note that it also makes sense to here to use the BCL Stack<T> type, which is exactly what you need, instead of reinventing the wheel using List<T>.

public static void PushRange<T>(this Stack<T> source, IEnumerable<T> collection)
{
    foreach (var item in collection)
        source.Push(item);
}

Which would then allow you do the following:

myStack.PushRange(myCollection);

And if you're not already convinced, another philosophical reason: LINQ was created to bring functional paradigms to C#/.NET, and at the core of functional programming is side-effect free code. Combining LINQ with state-modifying code would thus be quite inconsistent.

Noldorin
Why an extension method? The stack class seems to be written by him, so a normal method would be better imho.
Maximilian Mayerl
@Maximillian: Look closer at my code. The method takes a `Stack<T>` parameter, not a `List<T>` one. He seems to be reinventing the wheel here, for which there is no need.
Noldorin
Ah, you suggest creating an extension method for the BCL's Stack class, not for his. Okay, this makes sense, of course. Sorry for the misunderstading.
Maximilian Mayerl
@Maximillian: No worries. :) And yeah, I didn't initially make it explicit that I was instructing him to use `Stack<T>` instead.
Noldorin
Yes Now I can understand the purpose of linq ! Thanks
+1  A: 

The first issue is you Push returns a void. Select is expecting a value of something.

You are just doing a loop and don't need to use link.

Since you stack is internally storing a list, you can create a list by passing it an array.

so in your case

List<string> myList = new List<string>(array);

Creats the list.

David Basarab
+1  A: 

Push needs a return type for you to be able to use it in a select clause. As it is, it returns void. Your example is, I think, a horrible abuse of LINQ. Even if it worked, you'd be using a side-effect of the function in the select clause to accomplish something totally unrelated to the task that the select is intended for. If there was a "ForEach" extension, then it would be reasonable to use LINQ here, but I'd avoid it and stick with a foreach loop.

 foreach (var val in array)
 {
     slist.Push(val);
 }

This is much clearer in intent and doesn't leave one scratching their head over what you're trying to accomplish.

tvanfosson
+1  A: 

Change

public void Push(T obj)

to

public T Push(T obj)

and ignore the return values.

Disclaimer: I would not recommend mutation like this.

leppie
+1  A: 

Try this

string[] arr = new string[]{"a","f"};
var stack = new Stack<string>();
arr.ToList().ForEach(stack.Push);

While this is "cool" is isn't any better than a for loop.

Gary