Quantcast
Channel: Scott Hanselman's Blog
Viewing all articles
Browse latest Browse all 1148

Back to Basics: Moving beyond for, if and switch

$
0
0

I visit a lot of customers and look at a lot of code. I also worked with a number of large production code bases in my previous jobs and I see a lot of ifs, fors and switches. I see loops inside of loops with ifs inside them, all doing various transformations of data from one form to another. I see strings getting parsed to pull bits of data out in ways that are easy to say in English but take 100 lines to say in code.

Should they? When we are just getting started programming we learn about if first, then for, then the much abused switch statement.

I saw this little snippet on Miguel's blog a few weeks ago:

var biggerThan10 = new List;
for (int i = 0; i < array.Length; i++){
if (array [i] > 10)
biggerThan10.Add (array[i]);
}

It's straightforward. Take an array of ints and make a new list with those that are larger than 10. We've all see code like this a million times. Here's the same thing in a few other languages.

C#

var a = from x in array where x > 10 select x; 
var b = array.Where(x => x > 10);

Ruby

a = array.select{|x| x >10}

JavaScript

a = array.filter(function(x){return x > 10});

I'd much rather write these one line operations than the loop and if above. I still see this out in the world, so perhaps people haven't seen enough examples. I asked friends on Twitter to submit their examples. Thank you Twitter friends!

Here's a few nice examples. Iron Shay has some nice LINQ examples on his blog. Please do share yours in the comments. Be sure to use <pre> tags.

NOTE: This is about "shoving stuff into one line" but rather looking at solutions that are equally as readable but also simpler, terser, and less error prone than loops of loops.


def calculate_primes(n):
no_primes = []
primes = []

for i in range(2, 8):
for j in range(i*2, n, i):
no_primes.append(j)

for x in range(2, n):
if x not in no_primes:
primes.append(x)

return primes


calculate_primes(500)


# Can be like this instead!

(lambda n: [x for x in range(2, n) if x not in [j for i in range(2, 8) for j in range(i*2, n, i)]])(500)

From Aaron Bassett


foreach (var i in categories) {
foreach (var x in GetAllChildCategories(i.Id)) {
yield return x;
}
}

//Can be...

return categories.SelectMany(i => this.GetAllChildCategoriesIds(i.Id));

From James Hull


var inputNumbersInString = Console.ReadLine();
var inputNumbersStringArray = inputNumbersInString.Split(' ');
var inputNumbers = new List<int>();

for (int i = 0; i < inputNumbersStringArray.Length; ++i) {
inputNumbers.Add(int.Parse(inputNumbersStringArray[i]));
}

int maxNumber = inputNumbers[0];

for (int i = 1; i < inputNumbers.Count; ++i)
if (inputNumbers[i] > maxNumber)
maxNumber = inputNumbers[i];

Console.WriteLine(maxNumber);

//Or rather...

Console.WriteLine(Console.ReadLine().Split(' ').Select(t => int.Parse(t)).ToList().Max());

From Amit Saraswat


// create a poker deck as a list of two characters strings: 
// rank, suite

char[] figures = "23456789TJQKA".ToCharArray();
char[] suites = "SHDC".ToCharArray();
List<string> deck = new List<string>();

foreach (var figure in figures) {
foreach (var suite in suites) {
deck.Add(string.Format("{0}{1}", figure, suite));
}
}

//Or, neatly
var cards = from r in "23456789TJQKA" from s in "SHDC" select "" + r + s;

From Jack Nova


bool include = false;
if (op == Operator.And) {
bool current = true;
foreach (var item in Items) {
current = current & item.Process();
}
include = current;
}
else {
bool current = false;
foreach (var item in Items) {
current = current | item.Process();
}
include = current;
}
return include;

//Or this lovely Aggregate

return op == Operator.And ?
Items.Aggregate(true, (current, item) => current & item.Process()) :
Items.Aggregate(false, (current, item) => current | item.Process());

From Kevin Meiresonne


sbyte[] sByteArray = new sbyte[100];
byte[] uByteArray = new byte[sByteArray.Length];

for (int i = 0; i < sByteArray.Length; i++) {
uByteArray[i] = (byte)sByteArray[i];
}

//Or, instead of the loop above
byte[] uByteArray1 = Array.ConvertAll(sByteArray, x => (byte)x);

From Fahad Mustafa


Scott: I have to say here that I prefer the first option. ;)

// This is the "classic" solution to the FizzBuzz problem.
for (int i = 1; i <= 100; i++) {
if (i % 3 == 0 && i % 5 == 0) {
Console.WriteLine("FizzBuzz");
}
else if (i % 3 == 0) {
Console.WriteLine("Fizz");
}
else if (i % 5 == 0) {
Console.WriteLine("Buzz");
}
else {
Console.WriteLine(i.ToString());
}
}

// One line
Enumerable.Range(1, 100).ToList().ForEach(n => Console.WriteLine((n % 3 == 0) ? (n % 5 == 0) ? "FizzBuzz" : "Fizz" : (n % 5 == 0) ? "Buzz" : n.ToString()));

From Rudi Larno


A good one...I'm surprised more people don't use this.

var temp = String.Empty;
foreach (var entry in myStringList) {
    if (String.IsNullOrEmpty(temp)) {
        temp = entry;
    }
    else {
        entry += ", " + entry;
    }
}

//becomes

var temp = String.Join(", ", myStringList)

From Holger Adam


A class with properties in one line of F#. That'd be a dozen or more lines of C#.

type Person = { Name:string; Age:int }

From Phillip Trelford


/// Input is a string with numbers : 10+20+30+40
/// Output is integer with required sum (100)
string input = "10+20+30+40";
var result = Regex.Split(input, @"\D+").Select(t => int.Parse(t)).Sum();
Console.WriteLine("Result is {0}" ,result);

From Srinivas Iyengar


There are a million things available to the programmer beyond the first three keywords we learn. What are your favorite patterns (doesn't matter what language) that have helped you break away from the basics and move to the next level?


Sponsor: Big thanks to the folks at DevExpress for sponsoring this week's feed. Check out a free trial of CodeRush, one of my favorite products! Introducing CodeRush by DevExpress. The Visual Studio add-in that helps you create more reliable applications. Tools to build & maintain your code without getting in the way of your IDE.

© 2012 Scott Hanselman. All rights reserved.

Viewing all articles
Browse latest Browse all 1148

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>