mboost-dp1

Banal kode fejl (C# kode)


Gå til bund
Gravatar #1 - arne_v
8. maj 2024 14:29
(set på LinkedIn)

Nogle gang kan selv meget simple problemstillinger resultere i kode fejl hvis man ikke lige tænker sig om.

Problemet er at omskrive denne "ægte" LINQ:

real = from o in lst orderby o.A, o.B select o;

til metode kald med lambda.

Det er ikke svært men jeg vil tro at en del får den forkert i første forsøg.

Altså:

hangover = lst.OrderBy(o => o.A).OrderBy(o => o.B)

fremfor:

correct = lst.OrderBy(o => o.A).ThenBy(o => o.B);

Fuld kode og output:


using System;
using System.Collections.Generic;
using System.Linq;

namespace SortFun
{
public class Data
{
public int A { get; set; }
public int B { get; set; }
public override string ToString()
{
return string.Format("({0},{1})", A, B);
}

}
public class Program
{
public static void Main(string[] args)
{
List<Data> lst = new List<Data> { new Data { A = 2, B = 2 }, new Data { A = 2, B = 1 }, new Data { A = 1, B = 2 }, new Data { A = 1, B = 1 } };
Console.WriteLine("Original : {0}", String.Join(",", lst));
IEnumerable<Data> real = from o in lst orderby o.A, o.B select o;
Console.WriteLine("Real LINQ : {0}", String.Join(",", real));
IEnumerable<Data> hangover = lst.OrderBy(o => o.A).OrderBy(o => o.B);
Console.WriteLine("Hangover code : {0}", String.Join(",", hangover));
IEnumerable<Data> correct = lst.OrderBy(o => o.A).ThenBy(o => o.B);
Console.WriteLine("Correct code : {0}", String.Join(",", correct));
}
}
}


Original : (2,2),(2,1),(1,2),(1,1)
Real LINQ : (1,1),(1,2),(2,1),(2,2)
Hangover code : (1,1),(2,1),(1,2),(2,2)
Correct code : (1,1),(1,2),(2,1),(2,2)

Når man ser resultatet er det jo helt indlysende.

Men som så ofte ikke helt så indlysende inden man har set resultatet.
Gravatar #2 - arne_v
8. maj 2024 16:44
#1

Det samme kan laves i Groovy.


class Data {
int a
int b
@Override
String toString() {
return "($a,$b)"
}
}

lst = [ new Data(a: 2, b: 2), new Data(a: 2, b: 1), new Data(a: 1, b: 2), new Data(a:1, b: 1) ]
println("Original : $lst")
real = GQ { from o in lst orderby o.a, o.b select o }
println("Real GINQ : $real")
hangover = lst.sort { it.a }.sort { it.b }
println("Hangover code : $hangover")
correct = lst.sort { o1, o2 -> o1.a <=> o2.a ?: o1.b <=> o2.b }
println("Correct code : $correct")


Original : [(2,2), (2,1), (1,2), (1,1)]
Real GINQ : [(1,1), (1,2), (2,1), (2,2)]
Hangover code : [(1,1), (2,1), (1,2), (2,2)]
Correct code : [(1,1), (1,2), (2,1), (2,2)]

Men selvom Groovy koden er meget kompakt, så synes jeg at den lider af et problem nemligt at den korrekte løsning er ulæselig.
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login