locked
IEnumerable ... Check if all items are 0 RRS feed

  • Question

  • Hello,

    I have the following list: IList<YSeries> where YSeries class is as follows:

    public struct YSeries {
      public IEnumerable Data;
    }

    I need to check if all items in Data of all YSeries in IList<Series> are equal to 0.

    I tried Count, Where but YSeries.Data does not accept anything.

    Could someone, please, help me out?

    Thank you,

    Miguel

    Friday, October 12, 2012 10:43 PM

Answers

  • I was doing some testing with the Convert part and does not seem to work.

    Remember that ySeries is a IList<YSeries> so it does not have a Data property ...

    I tried the following:

    y.Cast<YSeries>().All(o => Convert.ToDouble(o.Data) == 0.0)

    But I also get an error:

    Unable to cast object of type 'System.Collections.Generic.List`1[System.Int32]' to type 'System.IConvertible'.

    In this case I used a YSeries of type int ...

    Basically, my idea would be join all YSeries into a single YSeries then, as you suggested, convert each data item to double, then compare to 0.0.

    Thank You,

    Miguel

    In that case, you'd typically want:

    y.Cast<YSeries>().SelectMany(l => l).All(i => i == 0);

    This will "flatten" the lists, so you'll end up with an IEnumerable<int>, which you can then just check directly (without running through convert).


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by MDMoura Thursday, October 18, 2012 8:24 PM
    Monday, October 15, 2012 4:59 PM
  • I was able to solve it using, where ySeries is a IList<YSeries>:

    ySeries.All(z => z.Data.Cast<Object>().All(o => Convert.ToDouble(o) == 0.0))

    What do you think?

    And when do you use a Struct?

    I am asking this because a see a lot of code using classes where I would use a Struct.

    In fact I very rarely see people using Structs. They often go to Classes ...

    Thank You,

    Miguel

    • Marked as answer by MDMoura Thursday, October 18, 2012 8:24 PM
    Monday, October 15, 2012 12:33 PM
  • Off the top of my head, you can use SelectMany to concatenate all the Data IEnumerables:

    IList<YList> yList = ...;
    
    var dataList = yList.SelectMany(y => y.Data.Cast<int>());
    

    You can apply the 'All' method on it to determine if all the Data values are 0:

    bool allZero = yList.SelectMany(y => y.Data.Cast<int>()).All(d => d == 0);




    Hey, look! This system allows signatures of more than 60 cha

    • Marked as answer by MDMoura Thursday, October 18, 2012 8:24 PM
    Monday, October 15, 2012 12:51 PM

All replies

  • You ideally would want to know what type is in the data:

    var allZero = YSeries.Data.Cast<double>().All(d => d == 0.0);
    

    If you don't know whether they're all doubles or ints etc, you could use convert:

    bool allZero = ySeries.Data.Cast<object>().All(o => Convert.ToDouble(o) == 0.0);

    On a side note - since YSeries contains an IEnumerable (reference type), it'd most likely make more sense as a class, and not a struct...


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by MDMoura Friday, October 12, 2012 11:59 PM
    • Unmarked as answer by MDMoura Monday, October 15, 2012 12:18 PM
    Friday, October 12, 2012 11:12 PM
  • I see ...

    I might need to change something on my development.

    Thank You,

    Miguel

    Friday, October 12, 2012 11:59 PM
  • On a side note - since YSeries contains an IEnumerable (reference type), it'd most likely make more sense as a class, and not a struct...

    I don't see the link between this and that.

    Monday, October 15, 2012 12:12 PM
  • I was doing some testing with the Convert part and does not seem to work.

    Remember that ySeries is a IList<YSeries> so it does not have a Data property ...

    I tried the following:

    y.Cast<YSeries>().All(o => Convert.ToDouble(o.Data) == 0.0)

    But I also get an error:

    Unable to cast object of type 'System.Collections.Generic.List`1[System.Int32]' to type 'System.IConvertible'.

    In this case I used a YSeries of type int ...

    Basically, my idea would be join all YSeries into a single YSeries then, as you suggested, convert each data item to double, then compare to 0.0.

    Thank You,

    Miguel

    • Marked as answer by MDMoura Thursday, October 18, 2012 8:24 PM
    • Unmarked as answer by MDMoura Thursday, October 18, 2012 8:24 PM
    Monday, October 15, 2012 12:22 PM
  • I was able to solve it using, where ySeries is a IList<YSeries>:

    ySeries.All(z => z.Data.Cast<Object>().All(o => Convert.ToDouble(o) == 0.0))

    What do you think?

    And when do you use a Struct?

    I am asking this because a see a lot of code using classes where I would use a Struct.

    In fact I very rarely see people using Structs. They often go to Classes ...

    Thank You,

    Miguel

    • Marked as answer by MDMoura Thursday, October 18, 2012 8:24 PM
    Monday, October 15, 2012 12:33 PM
  • Off the top of my head, you can use SelectMany to concatenate all the Data IEnumerables:

    IList<YList> yList = ...;
    
    var dataList = yList.SelectMany(y => y.Data.Cast<int>());
    

    You can apply the 'All' method on it to determine if all the Data values are 0:

    bool allZero = yList.SelectMany(y => y.Data.Cast<int>()).All(d => d == 0);




    Hey, look! This system allows signatures of more than 60 cha

    • Marked as answer by MDMoura Thursday, October 18, 2012 8:24 PM
    Monday, October 15, 2012 12:51 PM
  • I was doing some testing with the Convert part and does not seem to work.

    Remember that ySeries is a IList<YSeries> so it does not have a Data property ...

    I tried the following:

    y.Cast<YSeries>().All(o => Convert.ToDouble(o.Data) == 0.0)

    But I also get an error:

    Unable to cast object of type 'System.Collections.Generic.List`1[System.Int32]' to type 'System.IConvertible'.

    In this case I used a YSeries of type int ...

    Basically, my idea would be join all YSeries into a single YSeries then, as you suggested, convert each data item to double, then compare to 0.0.

    Thank You,

    Miguel

    In that case, you'd typically want:

    y.Cast<YSeries>().SelectMany(l => l).All(i => i == 0);

    This will "flatten" the lists, so you'll end up with an IEnumerable<int>, which you can then just check directly (without running through convert).


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by MDMoura Thursday, October 18, 2012 8:24 PM
    Monday, October 15, 2012 4:59 PM

  • And when do you use a Struct?

    I am asking this because a see a lot of code using classes where I would use a Struct.

    In fact I very rarely see people using Structs. They often go to Classes ...


    This is because class is almost always preferred in .NET.  There is actually official guidance on choosing between a class and a struct here: http://msdn.microsoft.com/en-us/library/vstudio/ms229017(v=vs.100).aspx

    Basically, you'd typically only want to use struct if ALL of the following are true:

    • It logically represents a single value, similar to primitive types (integer, double, and so on).

    • It has an instance size smaller than 16 bytes.

    • It is immutable.

    • It will not have to be boxed frequently.

    In your case, having a reference type within the struct pretty much guarantees that point 3 will be violated.  It also strongly suggests that it's not a "single value".  You're also boxing it every time you put it into a collection (such as your YSeries) by using a struct, so you violate the 4th point.  

    In general, the only time you really should use a struct is if you're making a small, single value - and ideally, you should make it immutable, as well (so there's no way to change it once its created).  


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Proposed as answer by Norkk Monday, October 15, 2012 5:05 PM
    Monday, October 15, 2012 5:02 PM
  • In your case, having a reference type within the struct pretty much guarantees that point 3 will be violated.

    As long as you don't provide a way to modify which instance is refered to, the value is immutable. I don't see data of objects referenced by a value as part of the data of that value.

    It also strongly suggests that it's not a "single value".

    I disagree with that too. I have an example in my head but I need to find the translation in English.

    You're also boxing it every time you put it into a collection (such as your YSeries) by using a struct, so you violate the 4th point.

    That is a valid reason.

    Tuesday, October 16, 2012 8:06 AM
  • If you have a class defining a set of values and each value keeps a reference to the set, is the value no longer a value?
    Tuesday, October 16, 2012 8:38 AM
  • If you have a class defining a set of values and each value keeps a reference to the set, is the value no longer a value?

    If you have a class defining a set of values, having a "single value" keep a reference to an entire set makes that "single value" something other than one single value - it's making it a combination of multiple "concepts" - a value + a set.  As soon as its no longer a single value, it's likely inappropriate as a struct.

    There's a bigger problem with structs containing references, however - if the struct is immutable (which is typically the best option), there's no way to override the default constructor (correctly).  This means, by default, when you create the struct in many scenarios, you're going to always have an immutable null reference contained within your struct.  (For example, this will happen any time you create an array of structs).  This is often problematic, and again, typically a good reason to choose a class over a struct.


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Tuesday, October 16, 2012 4:10 PM
  • having a "single value" keep a reference to an entire set makes that "single value" something other than one single value

    It's making it a value related to a set. Say you have a set A {1, 2, 3} and a set B {2, 4, 6}. Is the second item of set A the same value as the first item of set B? If it makes sense to think they are not the same thing, then the value must depend on the set in some way. The null Set must be addressed. Maybe like this:

    public struct SetMember
    {
        Set set;
        int index;
        public int? Value
        {
            if (set == null)
                return null;
            else
                return set[index];
        }
        public SetMember(Set set, int index)
        {
            this.set = set;
            this.index = index;
        }
    }
    class Set
    {
        List<int> values;
        public Set(List<int> values)
        {
            this.values = values;
        }
        public SetMember this[int index]
        {
            return new SetMember(this, index);
        }
    }

    I don't think I'll ever use a struct like this. I don't claim it's a good idea. But if it isn't, I think it's not because of one of the 4 rules in the official guidelines.

    Wednesday, October 17, 2012 7:25 AM
  • Ahh - I see what you're saying.  I wasn't being very clear, but I was meaning if you have a publically accessible reference to a reference type within a value type.  In your case, SetMember is completely encapsulating that - so it's potentially a decent candidate for struct.  (It's similar in concept to ArraySegment<T>, btw: http://msdn.microsoft.com/en-us/library/1hsbd92d.aspx).

    Anyways - there are always exceptions to all of these "rules" (which are really just guidelines) - but I still think, in general, a reference type stored within a value type is rarely a good idea.  It's almost always a sign that a class would make more sense (though I do agree, there are execptions ;) ).


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Wednesday, October 17, 2012 3:58 PM
  • Thank you for the help and for all the information on Class vs Struct.

    Thank You,

    Miguel

    Thursday, October 18, 2012 8:25 PM