Laden...

array shrinken auf das gemeinsame item

Erstellt von userid14268 vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.130 Views
U
userid14268 Themenstarter:in
1.578 Beiträge seit 2009
vor 15 Jahren
array shrinken auf das gemeinsame item

heiho,

ich fummel mich hier schon zu tode aber komm nicht drauf

ich hab ein array das ist beliebig lang und hat bestimmte objekte enthalten

zb
Item[] items = new Item[] { new Item("abba"), new Item("obbo"), new Item(null), new Item("abba") }

ich will nun raus finden ob alle items gleich sind
im beispiel waere es false

Item[] items = new Item[] { new Item("abba"), new Item(null) }
ist auch false aber

Item[] items = new Item[] { new Item("abba"), new Item("abba"), new Item("abba") }
waere true

ich hab bisher versucht etwas mit linq hin zu bekommen, aber so richtig weiss ich nicht weiter
ich muss nur wissen ob die items identisch sind
die werte koennen ueber ein property abgefragt werden - wobei das property nur zugaenglich ist wenn es nicht null ist

jemand ne idee ?

//dazuedit

was ich bisher habe:


bool identical = true;
for (int i = 0; i < itemList.Count - 1; ++i)
{
    Item firstItem = itemList[i];
    Item secondItem = itemList[i + 1];
    if ((firstItem.Inner == null && secondItem.Inner != null) ||
        (firstItem.Inner != null && secondItem.Inner == null))
    {
        identical = false;
        break;
    }
    else if ((firstItem.Inner != null && secondItem.Inner != null) &&
              (!firstItem.Inner.Value.Equals(secondItem.Inner.Value)))
    {
        identical = false;
        break;
    }
}
// identical ==  true || false

C
401 Beiträge seit 2007
vor 15 Jahren

if(itemlist[0] != null)
{
    foreach(Item item in itemList)
    {
        if(item == null || item.Inner != itemList[0].Inner)
        {
            identical = false;
            break;
        }
    }
}

Hoffe das hilft dir.

Gruß

Dario

R
234 Beiträge seit 2007
vor 15 Jahren

@Corpsegrinder: Rein vom Gefühl her würde ich sagen, dass das nicht funktioniert. Du vergleichst ja alle Items nur mit dem ersten und nicht jedes mit jedem.

/Edit: Oh, das ist natürlich totaler Schwachsinn von mir. Erst denken, dann schreiben ...

Hier trotzdem mein generischer Ansatz (wobei deiner dann warscheinlich performanter ist):


static bool AlleItemsGleich<T>(T[] list) where T : IComparable {
	for(int i = 0; i <= list.Length - 1; i++) {
		for(int u = i; u <= list.Length - 1; u++) {
			if(!list[i].Equals(list[u])) {
				return false;
			}
		}
	}
	return true;
}

1.361 Beiträge seit 2007
vor 15 Jahren

Array.Exists(itemList, p => p != itemList[0]);

(Wenn das Array leer ist, muss du noch nen Sonderfall einführen

beste Grüße
zommi

U
userid14268 Themenstarter:in
1.578 Beiträge seit 2009
vor 15 Jahren

beide vorschlaege gehen nicht da es wie gesagt auch null sein kann

ich muss ein properties von einen inneren obect abfragen, dieses objekt kann aber null sein

dh

item.Inner.Value == item.Inner.Value

wobei "Inner" vorher gegen null geprueft werden muss
wenn es der blanke wert waere waers kein problem
denn wenn nicht kann Value nicht gecheckt werden {o;

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Mr Evil,

und wo ist das Problem? Dann prüfst du halt vorher auf null.

Beachte bitte auch [Hinweis] Wie poste ich richtig? Punkt 1.1.1.

herbivore

U
userid14268 Themenstarter:in
1.578 Beiträge seit 2009
vor 15 Jahren

das problem ?
wie kann ich das in einem kuerzeren statement unterbringen das ein element sobald es null ist unterschiedlich ist (sofern nicht alle anderen auch null) und am sonsten die variable daraus

siehe meine bisherige loesung
mit den vorschlaegen wie man das kuerzer machen koennte geht das nicht, da man da nicht noch (wenn != null) einbauen kann, und wenn doch solls ja nicht uebersprungen werden da es ja sein kann das alle null sind und dann solls doch wieder true geben


static bool AlleItemsGleich<T>(T[] list) where T : IComparable {
    for(int i = 0; i <= list.Length - 1; i++) {
        for(int u = i; u <= list.Length - 1; u++) {
            if(!list[i].Equals(list[u])) {
                return false;
            }
        }
    }
    return true;
}

geht nicht, da "null" nicht vom typ IComparable sein kann, dh ich muesste es ausgrenzen, dann hab ich aber den fall "alle null" nicht abgedeckt (und zudem muss ein property in dem item abgefragt werden, nicht das item selber)


Array.Exists(itemList, p => p != itemList[0]);

geht auch nicht, da ich das item nicht direkt vergleichen muss sondern ein property daraus
also
p.Inner.Value != itemList[0].Inner.Value
und dort muss ich auch vorher pruefen das Inner nicht null ist

..
punkt 1.1.1. kannst du dir schenken - die grundlagen kenn ich zur genuege, ich vermute du hast den thread bisher nur ueberflogen? am sonsten hab ich mich evtl nicht gut genug ausgedrueckt - wenn dem so ist tuts mir leid - hoff das das problem nun klar ist

mal ein fallbeispiel
wir haben die klasse "Item" und die "Inner" klasse, die sehen folgendermaßen aus


public class Item
{
    public Inner { get; set; }
    public Item(string innerText)
    {
        if (!string.IsNullOrEmpty(innerText)
            Inner = new Inner() { Value = innerText };
    }
}

public class Inner
{
    public string Value { get; set; }
}

nun bin ich in einer anderen klasse und habe listen davon


List<Item> items1 = new List<Item>();
items1.Add(new Item("bla"));
items1.Add(new Item("bla"));
items1.Add(new Item("fasel"));
items1.Add(new Item(null));
items1.Add(new Item("bla"));

List<Item> items2 = new List<Item>();
items2.Add(new Item("bla"));
items2.Add(new Item("bla"));
items2.Add(new Item("bla"));

List<Item> items3 = new List<Item>();
items3.Add(new Item(null));
items3.Add(new Item(null));
items3.Add(new Item(null));

nun brauch ich eine funktion die ueberprueft ob die items in "itemsN" gleich sind, aber lediglich das Value von Inner muss gecheckt werden, da andere properties unterschiedlich sein koennen
items1 == unterschiedlich
items2 == gleich
items3 == gleich

bisher habe ich:


bool identical = true;
for (int i = 0; i < itemList.Count - 1; ++i)
{
    Item firstItem = itemList[i];
    Item secondItem = itemList[i + 1];
    if ((firstItem.Inner == null && secondItem.Inner != null) ||
        (firstItem.Inner != null && secondItem.Inner == null))
    {
        identical = false;
        break;
    }
    else if ((firstItem.Inner != null && secondItem.Inner != null) &&
              (!firstItem.Inner.Value.Equals(secondItem.Inner.Value)))
    {
        identical = false;
        break;
    }
}

nur ich find das irgendwie total haesslich

1.361 Beiträge seit 2007
vor 15 Jahren

    public static bool EqualityNullOrValue(Inner a, Inner b)
    {
        if (a == b)
            return true;
        if (a == null || b == null)
            return false;
        return (a.Value == b.Value);
    }

...

    items1.Exists(p => !EqualityNullOrValue(p.Inner, items1[0].Inner));

Du kannst das oben auch gerne per Extension Method als "NullableEquals"-Methode verwenden. Je nachdem, was die lieber ist.

beste Grüße
zommi

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Mr Evil,

ich muss noch mal auf [Hinweis] Wie poste ich richtig? Punkt 1.1.1 hinweisen. Dein "Problem" ist trivial. Eine Vergleichsbedigung oder eine Vergleichsmethode zu schreiben, die nicht nur Value berücksichtigt, sondern vorher überprüft, ob überhaupt ein Objekt vorhanden ist, dessen Value man vergleichen kann, hättest du auch selbst hin bekommen können.

Davon abgesehen ist es wie schon oben diskutiert nicht nötig und vor allem nicht sinnvoll jedes Element mit jedem zu vergleichen. Es reicht, wenn du zwei benachbarte Elemente vergleichst. Denn Gleichheit ist transitiv.

herbivore