Anagram checker

Check whether an anagram contains all the letters in the source text. Choose to compare only letters, letters and numbers, or all characters.

Face with waiting expression Nothing to see yet!

Loading takeymakey...
TakeyMakey code
Want this tool to do something else? Edit the code below and make it do whatever you want.
export const take = [
  { type: "text", label: "Source text", inline: true },
  { type: "text", label: "Anagram text", inline: true },
  {
    type: "dropdown",
    label: "Compare",
    options: [
      { label: "Letters only", value: /[a-z]/ },
      { label: "Numbers and letters", value: /[a-z\d]/ },
      { label: "Everything", value: /./ },
    ],
  },
]

export const make = ([a, b, rx]) => {
  let result = []
  let message = "Your anagram doesn't match yet."
  let value = false

  const da = diff(a, b, rx)
  const db = diff(b, a, rx)

  if (da.length > 0) {
    result.push({
      type: "text",
      label: "Missing characters",
      value: da.join(" "),
      inline: true,
    })
  }

  if (db.length > 0) {
    result.push({
      type: "text",
      label: "Extra characters",
      value: db.join(" "),
      inline: true,
    })
  }

  if (da.length === 0 && db.length === 0) {
    value = true
    message = "Your anagram contains all the letters!"
  }

  return [{ type: "status", value, message }, ...result]
}

const diff = (a, b, rx) => {
  a = a.toLowerCase().replace(/s/g, " ")
  b = b.toLowerCase().replace(/s/g, " ")

  return a
    .split("")
    .filter((c) => {
      if (!rx.test(c)) return false

      const index = b.indexOf(c)

      if (index < 0) return true

      b = b.slice(0, index) + b.slice(index + 1)

      return false
    })
    .map((c) => (c === " " ? "Space" : c))
}