17 lines of JS code became 1 line after this simple trick

Last updated on March 23, 2024
17 lines of JS code became 1 line after this simple trick

How did these 17 lines of JavaScript code turn into a one-liner function?

It's easy, you'll see!

The 1st thing we notice is we're selecting items from an array - this should NEVER take 3 lines in JavaScript!

We have the destructuring operator to turn this:

function extractRedirects(str) {
  const lines = str.split('\n');
  const sourceDestinationList = [];

  for (const line of lines) {
    const sourceDestination = line.split(' ');
    const source = sourceDestination[2];
    const destination = sourceDestination[3];
    const redirectObj = {
      source: source,
      destination: destination,
      permanent: true,
    };
    sourceDestinationList.push(redirectObj);
  }
  return sourceDestinationList;
}

into this:

function extractRedirects(str) {
  const lines = str.split('\n');
  const sourceDestinationList = [];

  for (const line of lines) {
    // ✅ Skip 1st two with comma placeholders!
    const [, , source, destination] = line.split(' ');
    const redirectObj = {
      source: source,
      destination: destination,
      permanent: true,
    };
    sourceDestinationList.push(redirectObj);
  }
  return sourceDestinationList;
}

What else is obvious? A loop and a gradual accumulation (with push).

Which means we're easily cutting out statements here with map() or reduce():

reduce works well anywhere but map is the natural choice since 1 array clearly transforms to another here.

So we go from this:

function extractRedirects(str) {
  const lines = str.split('\n');
  const sourceDestinationList = [];

  for (const line of lines) {
    const [, , source, destination] = line.split(' ');
    const redirectObj = {
      source: source,
      destination: destination,
      permanent: true,
    };
    sourceDestinationList.push(redirectObj);
  }
  return sourceDestinationList;
}

To this:

function extractRedirects(str) {
  const lines = str.split('\n');
  const sourceDestinationList = lines.map((line) => { // ✅
    const [, , source, destination] = line.split(' ');
    const redirectObj = {
      source: source,
      destination: destination,
      permanent: true,
    };
    // ✅
    return redirectObj;
  });
  return sourceDestinationList;
}

The declaration, for loop and push() have all been eradicated.

Now removing the temporary variable:

function extractRedirects(str) {
  const lines = str.split('\n');
  const sourceDestinationList = lines.map((line) => {
    const [, , source, destination] = line.split(' ');
    return {
      source: source,
      destination: destination,
      permanent: true,
    };
  });
  return sourceDestinationList;
}

And combining the last 2 statements in map's callback - without calling split() twice.

function extractRedirects(str) {
  const lines = str.split('\n');
  const sourceDestinationList = lines.map((line) => {
    return line.split(' ').reduce(
      (acc, curr, i) => {
        return i === 2
          ? { ...acc, source: curr }
          : i === 3
          ? { ...acc, destination: curr }
          : acc;
      },
      { permanent: true }
    );
  });
  return sourceDestinationList;
}

reduce() has a way of making your head spin!

Let's go with this instead; much more readable:

function extractRedirects(str) {
  const lines = str.split('\n');
  const sourceDestinationList = lines
    .map((line) => {
      return line.split(' ');
    })
    .map(([, , source, destination]) => {
      return {
        source: source,
        destination: destination,
        permanent: true,
      };
    });
  return sourceDestinationList;
}

Now we can remove the callback braces, from (a) => { return { b; } } to (a) => ({ b }):

function extractRedirects(str) {
  const lines = str.split('\n');
  const sourceDestinationList = lines
    .map((line) => line.split(' '))
    .map(([, , source, destination]) => ({
      source: source,
      destination: destination,
      permanent: true,
    }));
  return sourceDestinationList;
}

All that's left now is to remove the 2 remaining temp vars and use implicit property values:

function extractRedirects(str) {
  return str
    .split('\n')
    .map((line) => line.split(' '))
    .map(([, , source, destination]) => ({
      source, // ✅
      destination, // ✅
      permanent: true,
    }));
}

Arrow function:

const extractRedirects = (str) =>
  str
    .split('\n')
    .map((line) => line.split(' '))
    .map(([, , source, destination]) => ({
      source,
      destination,
      permanent: true,
    }));

Yes refactors are fun; it's fun to see the function gradually evolve and grow in a compact one-liner form.

And it wasn't just for fancy; With it I moved a GIGANTIC amount of redirect information...

From painful, dinosaur WP Apache .htaccess:

They were way more than 5!

To lovely, modern next.config.js

And it worked perfectly.

Coding Beauty Assistant logo

Try Coding Beauty AI Assistant for VS Code

Meet the new intelligent assistant: tailored to optimize your work efficiency with lightning-fast code completions, intuitive AI chat + web search, reliable human expert help, and more.

See also