DRYing up jQuery FizzBuzz Exercise

114 Views Asked by At

I've run into an issue where I cannot save the repeated lines of code into variables and unsure why. Aside from that, I'm trying to set the new table next to the current instead of under or above it, but I haven't been able to manipulate the DOM to reflect that. Any and all help would be greatly appreciated.

(function($) {
$.fn.fizzBuzz = function() {
 var newTable = $(this).clone();
 var myTable = $(this.children().last().children());
 // var newTableValues = newTable.children().last().children()[i].firstChild.innerHTML;
 // var parseData = (parseInt(myTable[i].firstChild.innerHTML)

 for (var i = 0; i < myTable.length; i++) {

  if (parseInt(myTable[i].firstChild.innerHTML) % 15 === 0) {
    newTable.children().last().children()[i].firstChild.innerHTML  = "FizzBuzz";

  } else if (parseInt(myTable[i].firstChild.innerHTML) % 3 === 0) {
    newTable.children().last().children()[i].firstChild.innerHTML = "Fizz";

  } else if (parseInt(myTable[i].firstChild.innerHTML) % 5 === 0) {
    newTable.children().last().children()[i].firstChild.innerHTML = "Buzz";

  } else {
    newTable.children().last().children()[i].firstChild.innerHTML = "Uncool";
 }
  newTable.insertAfter('div');
}
}
})(jQuery)

$(".fizzer").fizzBuzz();

jsfiddle

1

There are 1 best solutions below

1
On BEST ANSWER
(function($) {
    $.fn.fizzBuzz = function() {
        var newTable = $(this).clone();
        $("tr > td", newTable).each(function(i, e) {
            var i = parseInt(e.innerHTML, 10);
            var f = (i % 3 == 0 ? "Fizz" : "") + (i % 5 == 0 ? "Buzz" : "");
            e.innerHTML = f ? f : "Uncool";
        });
    return newTable;
}
})(jQuery);

var newTable = $(".fizzer").fizzBuzz();
$("#main").append(newTable);

It doesn't get much DRYer than that.
(1) Your new table is a copy of your existing table. Once you've cloned your existing table, leave it alone.

(2) Avoiding all the children/last/etc stuff if you can; use CSS selectors whenever possible.

(3) If you're dependent upon reading numbers out of JSON or HTML, always run it through parseInt()

(4) jQuery has a lot of useful facilities for iterating through DOM objects that are superior to anything you can possibly write, mostly because since you don't write anything you don't introduce bugs. Instead of your for() loop, learn how each() and map() can save you time and frustration. Learn the difference between jQuery.each() and Array.each(), especially, and their .map() equivalents.

(5) By using jQuery's "each" function with CSS selectors, I get access to the exact target I care about. I'm able to analyze it and replace its contents (this all happens in the copy).

(6) Since I'm building a new DOM object, rather than manipulate it in the function, I return it, and let the user decide where to put it.

(7) Unless I have a specific documentation need to help future maintainers understand the code, the only variables I ever declare are those I use more than once.

(8) The two instances of newTable are completely independent. The one inside my fizzBuzz function is scoped, and will not affect the outer one, or vice versa. Always use var.