SEI-Example
  • Introduction
  • About These Notes
  • Syllabus
  • Development Workflow
    • Installfest
      • Mac OSX
      • Linux
      • Git Configuration
      • Sublime Packages
    • Command Line
      • The Terminal
      • Filesystem Navigation
      • File Manipulation
      • Additional Topics
    • Intro to Git
      • Version Control
      • Local Git
      • Remote Git
      • Git Recipes
    • Group Collaboration
      • Git Workflows
      • Project Roles and Tools
    • VS Code Tips & Tricks
  • HTML/CSS
    • HTML
    • CSS Selectors
    • CSS Box Model and Positioning
      • Box Model
      • Display and Positioning
      • Flexbox
      • Grid
      • Flexbox & Grid Games
      • Floats and Clears
      • Additional Topics
    • Advanced CSS
      • Responsive Design
      • Pseudo-Classes/Elements
      • Vendor Prefixes
      • Custom Properties
      • Additional Topics
    • Bootstrap
    • CSS Frameworks
    • Accessibility
  • JavaScript
    • Primitives
    • Arrays
    • Objects
    • Control Flow
      • Boolean Expressions
      • Conditionals
      • Loops
      • Promises
    • Functions
      • Callbacks
      • Timing Functions
      • Iterators
    • DOM and Events
    • DOM Manipulation
    • HTML5 Canvas
    • How To Reduce Redundancy
    • (2019) JavaScript OOP
    • (2016) OOP with Classes
    • (1995) OOP with Prototypes
      • Constructors
      • Prototypes
    • Intro to TDD
    • Scoping
    • Inheritance
      • Prototypal Inheritance
      • Call, Apply, and other Functions
      • ES6 Inheritance
      • Resources
    • Custom Node Modules
    • Additional Topics
      • AJAX, Fetch, and Async/Await
      • AJAX w/JSON and Localstorage
        • AJAX w/JSON
        • Local Storage
      • Async module
      • Data Scraping
  • jQuery
    • Intro
      • DOM Manipulation
      • Reddit Practice
      • Styling
      • Events
    • Plugins
    • AJAX
  • APIs
    • Fetch
    • AJAX w/jQuery
    • AJAX w/Fetch
  • Databases
    • Intro to SQL
    • Advanced SQL
    • MongoDB
      • Intro to NoSQL
      • CRUD in MongoDB
      • Data Modeling
      • Intermediate Mongo
  • Node/Express
    • Node
      • Intro to Node
      • Node Modules
      • Node Package Manager (NPM)
    • Express
      • Intro to Express
        • Routes
        • Views
        • Templates
        • Layouts and Controllers
        • CRUD & REST
          • Get and Post
          • Put and Delete
      • APIs with Express (request)
      • APIs with Express (axios)
    • Sequelize
      • Terminology
      • Setup
      • Using Models
      • Seeding Data
      • Validations and Migrations
      • Resources
      • 1:M Relationships
      • N:M Relationships
    • Express Authentication
      • Research Components
      • Code Components
      • Auth in Theory
        • Sessions
        • Passwords
        • Middleware
        • Hooks
      • Auth in Practice
        • Create the User
        • User Signup
        • Sessions
        • User Login
        • Authorization and Flash messages
    • Testing with Mocha and Chai
    • Mongoose
      • Mongoose Associations
    • JSON Web Tokens
      • Codealong
    • Additional Topics
      • oAuth
      • Geocoding with Mapbox
      • Geocoding and Google Maps
      • Cloudinary
      • Websockets with Socket.io
      • SASS
  • Ruby
    • Intro to Ruby
    • Ruby Exercises
    • Ruby Classes
    • Ruby Testing with Rspec
    • Ruby Inheritance
    • Ruby Data Scraping
  • Ruby on Rails
    • Intro to Rails
    • APIs with Rails
    • Asset Pipeline
    • Rails Auth and 1-M
      • Auth Components
    • Rails N:M
    • ActiveRecord Polymorphism
    • Additional Topics
      • oAuth
      • SASS
      • Rails Mailers
      • Cloudinary
      • Jekyll
  • React (Updated 2019)
    • ES6+/ESNext
      • Const and Let
      • Arrow Functions
      • Object Literals and String Interpolation
      • ES6 Recap
      • ES6 Activity
    • Intro to React
      • Create React App
      • Components and JSX
      • Virtual DOM
      • Props
      • Dino Blog Activity
      • Nested Components
      • Lab: LotR
    • React State
      • Code-Along: Mood Points
      • Code-Along: Edit Dino Blog
      • Lab: Simple Calc
      • Lifting State
    • React Router
      • Browser History/SPAs
      • React Router (lesson and full codealong)
      • Router Lab
    • Fetch and APIs
      • APIs with Fetch and Axios
      • Fetch the Weather
    • React Hooks
    • React LifeCycle
      • Lab: Component LifeCycle
    • React Deployment
    • Additional Topics
      • React Frameworks
        • Material UI Theming
      • Typescript
        • More Types and Syntax
        • Tsconfig and Declaration Files
        • Generics with Linked List
      • Redux
      • TypeScript
      • Context API
      • React Native
  • Meteor
  • Deployment and Config
    • Deploy - Github Pages
    • Deploy - Node/Sequelize
    • Deploy - Node/MongoDB
    • Deploy React
    • Deploy - Rails
      • Foreman (Environment Variables)
    • Deploy - AWS Elastic Beanstalk
    • Deploy - S3 Static Sites
    • Deploy - Django
    • Deploy - Flask
  • Data Structures and Algorithms
    • Recursion
    • Problem Solving - Array Flatten
    • Binary Search
    • Algorithm Complexity
    • Stacks and Queues
    • Bracket Matching
    • Ruby Linked Lists
      • Sample Code
      • Beginner Exercises
      • Advanced Exercises
    • JS Linked Lists
      • Sample Code
      • Beginner Exercises
      • Beginner Solutions
    • Hash Tables
    • Intro to Sorting
    • Insertion Sort
    • Bucket Sort
    • Bubble Sort
    • Merge Sort
    • Quick Sort
    • Heap Sort
    • Sorting Wrapup
    • Hashmaps
    • Trees and Other Topics
  • Python
    • Python Installation
    • Intro to Python
    • Python Lists
    • Python Loops
    • Python Dictionaries
    • Python Sets and Tuples
    • Python Cheatsheet
    • Python Functions
    • Python Classes
    • Python Class Inheritance
    • Intro to Flask
    • Intro to SQLAlchemy
      • Flask and SQLAlchemy
    • Using PyMongo
    • Intro to Django
    • CatCollector CodeAlong
      • URLs, Views, Templates
      • Models, Migrations
      • Model Form CRUD
      • One-to-Many Relations
      • Many-to-Many Relations
      • Django Auth
    • Django Cheatsheet
    • Django Auth
    • Django Polls App Tutorial
    • Django School Tool Tutorial
    • Django 1:M Relationships
    • Custom Admin Views
    • Data Structures and Algorithms
      • Recursion
      • Binary Search
      • Stacks and Queues
      • Linked Lists
      • Binary Trees
      • Bubble Sort
      • TensorFlow & Neural Networks
    • Adjacent Topics
      • Raspberry Pi
      • Scripting
  • Assorted Topics
    • History of Computer Science
    • Regular Expressions
    • Intro to WDI (Course Info)
    • Being Successful in WDI
    • Internet Fundamentals
      • Internet Lab
    • User Stories and Wireframing
      • Wireframing Exercise: Build an Idea
    • Post WDI
      • Learning Resources
      • Deliverables -> Portfolio
      • FAQ
  • Projects
    • Project 1
    • Project 2
    • Project 3
      • Project 3 Pitch Guidelines
    • Project 4
    • Past Projects
      • Project 1
      • Project 2
      • Project 3
      • Project 4
      • Portfolios
    • Post Project 2
    • MEAN Hackathon
      • Part 1: APIs
      • Part 2: Angular
    • Portfolio
  • Web Development Trends
  • Resources
    • APIs and Data
    • Tech Websites
    • PostgreSQL Cheat Sheet
    • Sequelize Cheat Sheet
    • Database Administration
  • Archived Section
    • (Archived) ReactJS
      • Intro to React
        • Todo List Codealong
        • Additional Topics
      • Deploy React
      • React with Gulp and Browserify
        • Setting up Gulp
        • Additional Gulp Tasks
      • React Router
        • OMDB Router
        • OMDB Search
        • Additional Resources
      • React Animations
        • CSS Animations
    • AngularJS
      • Intro to AngularJS
        • Components and SPA
        • Create an Angular App
      • Angular Directives and Filters
      • Angular Animation
      • Angular Bootstrap Directives
        • Bootstrap Modals
      • Angular $http
      • Angular Services
        • Service Recipes
        • ngResource
        • Star Wars Codealong
      • Angular Routing
      • Angular + Express
      • Angular Authentication
        • Additional Topics
      • Angular Components
      • Angular Custom Filters
      • Angular Custom Directives
Powered by GitBook
On this page
  • Learning Objectives
  • What is Redundany?
  • Flipping Boolean Values
  • Iterating Through Numbers
  • Factoring if/else Branches
  • Encapsulating Redundancy With Functions
  • Encapsulating Redundancy With Functions (again)
  • Using Variables to Reduce Redundancy
  • Exercise 1
  • Exercise 2
  • Exercise 3
  1. JavaScript

How To Reduce Redundancy

Imagine someone telling you to pick up a few things at the grocery store:

"Go to the Safeway at 50th and Brooklyn in the U-District by the Jack in the Box and pick us up a gallon of milk. Oh, also, while you're at the Safeway at 50th and Brooklyn in the U-District by the Jack in the Box you should also buy a 12-pack of Mountain Dew. It's a fun errand. The cashier guy at that Safeway at 50th and Brooklyn in the U-District by the Jack in the Box is hilarious."

Wow. Why did they have to tell us exactly where it is so many times? We got the idea the first time they clarified it. Although it's easy to see that telling someone the exact location of a Safeway several times in conversation is unnecessary in a conversation, it's easy to make the same sort of mistake in programming.

Learning Objectives

  • define redundancy

  • identify examples of redundancy

  • see how to reduce redundancy

  • practice reducing redundancy

What is Redundany?

Redundancy is any code that repeats itself unnecessarily. Redundant code can take a long time to write. Redundant code exposes programs to silly errors, like increasing the likelihood of making a typo when you type something several times, or making a change in 9/10 places, but forgetting to make a change in the last tenth place.

Programmers like to reduce redundancy for several reasons:

  • code becomes easier to read

  • code becomes easier to maintain

  • code may become more efficient because a computer doesn't have to

    process identical operations over and over again.

  • it's easier to make changes to

  • changes made in just one place are guaranteed to be consistently the same.

  • sometimes programmers just like to write code because it's shorter and

    faster to write!

Here's a collection of several examples of redundant code and what you can do to prevent redundancy.

Flipping Boolean Values

It's super common to flip a boolean value back and forth between true and false. Instead of using a four-line if/else structure, you can use the not operator to turn true into false and false into true. Here's your options:

if (booleanValue === true) {
  booleanValue = false;
} else {
  booleanValue = true;
}
booleanValue = !booleanValue;

Iterating Through Numbers

Here we're trying to write code that steps us through the strings cell0, cell1, cell2 ... up to cell8. We don't need to write this all out manually.

It's possible to use a for loop to step through the sequence of numbers we need, and we can use string concatenation to build up the string we need.

document.getElementById("cell0").textContent="";
document.getElementById("cell0").style.backgroundColor= "white";
document.getElementById("cell1").textContent="";
document.getElementById("cell1").style.backgroundColor= "white";
document.getElementById("cell2").textContent="";
document.getElementById("cell2").style.backgroundColor= "white";
document.getElementById("cell3").textContent="";
document.getElementById("cell3").style.backgroundColor= "white";
document.getElementById("cell4").textContent="";
document.getElementById("cell4").style.backgroundColor= "white";
document.getElementById("cell5").textContent="";
document.getElementById("cell5").style.backgroundColor= "white";
document.getElementById("cell6").textContent="";
document.getElementById("cell6").style.backgroundColor= "white";
document.getElementById("cell7").textContent="";
document.getElementById("cell7").style.backgroundColor= "white";
document.getElementById("cell8").textContent="";
document.getElementById("cell8").style.backgroundColor= "white";
for (var i = 0; i < 9; i++) {
  document.getElementById("cell" + i).textContent="";
  document.getElementById("cell" + i).style.backgroundColor= "white";
}

Factoring if/else Branches

Whenever a piece of code appears in every branch of an if/else if/else statement we can factor it out so it appears just once immediately after the entire if statement.

Think of this like reducing a common denominator from a fraction. If every branch of an if/else statement is "divisible" by a statement then the statement can be "factored out" and written just just before or after the entire if/else statement.

6/8 = (2 * 3)/(2 * 4) = 3/4
if (whosTurn == "X"){
    whosTurn = "O";
    displayX(this);
} else {
    whosTurn = "X";
    displayO(this);
}
if (whosTurn == "X"){
    whosTurn = "O";
} else {
    whosTurn = "X";
}
displayO(this);

Encapsulating Redundancy With Functions

These two functions repeat code defining how to set a background image. We can make a third function that accepts a parameter representing The filename to be used as the background image, and each of the original functions can pass in their filename to the old function.

function displayX(thing) {
    thing.style.background = "url(img/cross.jpg) 0% 0% / cover";
}

function displayO(thing) {
    thing.style.background = "url(img/circle.png) 0% 0% / cover";
}
function displayX(thing) {
    displayImg(thing, "cross.jpg");
}

function displayO(thing) {
    displayImg(thing, "circle.png");
}

function displayImg(thing, filename) {
  thing.style.background = "url(img/" + filename + ") 0% 0% / cover";
}

Encapsulating Redundancy With Functions (again)

Create a helper function to encapsulate logical redundancy:

if(player === status[0] && player === status[1] && player === status[2]){
  return true;
} else if (player === status[0] && player === status[3] && player === status[6]){
  return true;
} else if (player === status[0] && player === status[4] && player === status[8]){
  return true;
} else if (player === status[1] && player === status[4] && player === status[7]){
  return true;
} else if (player === status[2] && player === status[4] && player === status[6]){
  return true;
} else if (player === status[2] && player === status[5] && player === status[8]){
  return true;
} else if (player === status[3] && player === status[4] && player === status[5]){
  return true;
} else if (player === status[6] && player === status[7] && player === status[8]){
  return true;
} else {
  return false;
}
if (threeInARow(player, status, 0, 1, 2) ||
    threeInARow(player, status, 0, 3, 6) ||
    threeInARow(player, status, 0, 4, 8) ||
    threeInARow(player, status, 1, 4, 7) ||
    threeInARow(player, status, 2, 4, 6) ||
    threeInARow(player, status, 2, 5, 8) ||
    threeInARow(player, status, 3, 4, 5) ||
    threeInARow(player, status, 6, 7, 8)) {
  return true;
} else {
  return false;
}

function threeInARow(player, status, i0, i1, i2) {
  if (player === status[i0] && player === status[i1] && player === status[i2]) {
    return true
  }
  return false;
}

Using Variables to Reduce Redundancy

If you're copying and pasting strings, you're probably writing redundant code. In this example we can save ourselves from writing a string twice. Instead of writing on both sides of an if/else statement we write it once at the end. The two parts of it that changes are saved as values in variables.

if (turn % 2 === 0) {
  elem.innerHTML = '<img src="img/xmark.png">';
  elem.dataset.content = "X";
} else {
  elem.innerHTML = '<img src="img/omark.png">';
  elem.dataset.content = "O";
}
var filename, content;

if (turn % 2 === 0) {
  filename = "xmark.png";
  content = "X";
} else {
  filename = "omark.png";
  content = "O";
}

elem.innerHTML = '<img src="img/' + filename + '">';
elem.dataset.content = content;

You can also write this to assume the variables have default values for the X turn and only update them to O values if it's O's turn.

var filename = "xmark.png";
var content = "X";

if (turn % 2 !== 0) {
  filename = "omark.png";
  content = "O";
}

elem.innerHTML = '<img src="img/' + filename + '">';
elem.dataset.content = content;

Exercise 1

Identify the redundancy in this code and get rid of it by using variables.

if (state % 4 === 0) {
  document.getElementById(this.id).textContent="X";
  this.style.backgroundColor = "red";
} else if (state % 4 === 1){
  document.getElementById(this.id).textContent="O";
  this.style.backgroundColor = "blue";
} else if (state % 4 === 2){
  document.getElementById(this.id).textContent="Z";
  this.style.backgroundColor = "yellow";
} else if (state % 4 === 3){
  document.getElementById(this.id).textContent="M";
  this.style.backgroundColor = "green";
}

Exercise 2

Create a function that creates an image tag and appends it to an element. The function should be parameterized so it can accept an id of the element to attach the image to, and second parameter for the filename of the iamge.

if (xTurn == true) {
    var xImg = document.createElement("img");
    xImg.src = "img/bacon-x.png";
    document.getElementById(this.id).append(xImg);
    xTurn = false;
} else {
    var xImg = document.createElement("img");
    xImg.src = "img/egg-o.png";
    document.getElementById(this.id).append(xImg);
    xTurn = true;
}

Exercise 3

There's some long lines that repeat themselves several times here. Create a function to reduce some redundancy here.

for(i=0; i<3; i++){
  if(tileStatus[i]==player & tileStatus[i+3]==player & tileStatus[i+6]==player){
    console.log(player+" matches column!");
    document.getElementById("tile"+i).className = document.getElementById("tile"+i).className + " win";
    document.getElementById("tile"+(i+3)).className = document.getElementById("tile"+(i+3)).className + " win";
    document.getElementById("tile"+(i+6)).className = document.getElementById("tile"+(i+6)).className + " win";
    return true;
  }
}
PreviousHTML5 CanvasNext(2019) JavaScript OOP

Last updated 3 years ago

Click to view answer

Click to view answer

Click to reveal answer