Home > Software engineering >  Better way of searching specific keywords in strings in JavaScript
Better way of searching specific keywords in strings in JavaScript

Time:08-27

I am working with an array of urls and for each url i wanna find a image corresponding to the site domain. my first attempt was

  const url = new URL(props.url);
  const platform = url.hostname.split(".")[1];
  console.log(platform)

  const platform_logos = {
    "codechef": "images/chef.png",
    "withgoogle": "images/google.png",
    .
    .
    .
    "codeforces": "images/codeforces.png",
  }

  let platform_logo = platform_logos[platform];

but it doesnt work with url of type 'https://momo2022fr.hackerearth.com' so i had to resort to

  let platform_logo = "images/code.png"

  if (url.includes("hackerearth")) {
    platform_logo = "images/hackerearth.png"
  }
  else if (url.includes("hackerrank")) {
    platform_logo = "images/hackerrank.png"
  }
  else if (url.includes("codeforces")) {
    platform_logo = "images/codeforces.png"
  }
  else if (url.includes("codechef")) {
    platform_logo = "images/chef.png"
  }
  else if (url.includes("atcoder")) {
    platform_logo = "images/atcoder.png"
  }
  else if (url.includes("leetcode")) {
    platform_logo = "images/leetcode.png"
  }
  else if (props.url.includes("withgoogle")) {
    platform_logo = "images/google.png"
  }

Is there any better way of writing the code below, it just feels like it violates DRY

CodePudding user response:

You can iterate over the images and check URL:

const url = "https://example.com/codechef/asdasd/...";
const platform_logos = {
    "codechef": "images/chef.png",
    "withgoogle": "images/google.png",
    "codeforces": "images/codeforces.png",
  }
  let img = "default.png";
  for (const [key, value] of Object.entries(platform_logos)) {
       if (url.includes(key)) {
           img = value;
           break;
       }
  }
  
  console.log(img);

CodePudding user response:

You could change how you're reading the url to only get the root domain.

location.hostname.split('.').reverse().splice(0,2).reverse().join('.').split('.')[0]

This code would give hackerearth for https://momo2022fr.hackerearth.com/.

CodePudding user response:

So there are several ways of achieving this. These are just two from the top of my head.

Parsing the url and using a switch() to determine the outcome, with fallback if none is found.

const url = new URL("https://www.withgoogle.com/search?q=test");
const sites = [
  "hackerearth",
  "hackerrank",
  "codeforces",
  "codechef",
  "atcoder",
  "leetcode",
  "withgoogle",
];

console.info(url.hostname);

const site = url.hostname.match(new RegExp(`${sites.join("|")}`));

let logo = "";

switch (site[0]) {
  case "hackerearth":
    logo = "images/hackerearth.png";
    break;
  case "hackerrank":
    logo = "images/hackerrank.png";
    break;
  case "codeforces":
    logo = "images/codeforces.png";
    break;
  case "codechef":
    logo = "images/chef.png";
    break;
  case "atcoder":
    logo = "images/atcoder.png";
    break;
  case "leetcode":
    logo = "images/leetcode.png";
    break;
  case "withgoogle":
    logo = "images/google.png";
    break;
  default:
    logo = "images/code.png";
    break;
}

console.info(logo);

Then there is the modern way, with less code and programming the fallback.

// const url = new URL("https://eee.com/test");
const url = new URL("https://www.withgoogle.com/search?q=test");
const sites = {
  hackerearth: "images/hackerearth.png",
  hackerrank: "images/hackerrank.png",
  codeforces: "images/codeforces.png",
  codechef: "images/chef.png",
  atcoder: "images/atcoder.png",
  leetcode: "images/leetcode.png",
  withgoogle: "images/google.png",
  default: "images/code.png",
};

let site = url.hostname.match(new RegExp(`${Object.keys(sites).join("|")}`));

if (site === null) {
  site = "default";
}

console.info(site, sites[site]);

CodePudding user response:

You could just do the same thing as in your first solution and store the mapping from the substring to the image path in an ocject:

const platform_logos = {
  "hackerearth": "images/hackerearth.png",
  "hackerrank": "images/hackerrank.png",
  "codeforces": "images/codeforces.png",
  "codechef": "images/chef.png",
  "atcoder": "images/atcoder.png",
  "leetcode": "images/leetcode.png",
  "withgoogle": "images/google.png"
};

Then you could iterate over the key-value pairs in your object to find the key that is part of the URL and return it once it matches:

function getLogo(url) {
  for(const [key, value] of Object.entries(platform_logos)) {
    if(url.contains(key)) {
      return value;
    }
  }
}

let platform_logo = getLogo(url);
  • Related