3

Okay, so this is something i partially have working (ignoring case sensitivity) comparing the following:

arrayA = ["apples", "Oranges", "salt", "Cracked Black Pepper"];
arrayB = ["salt", "pepper", "orange"]

which works 'partially' with the following:

findAnyMatch(arrayA, arrayB): string[] {
    let returnArray = [];
    let conditionedArrayA = arrayA.map(i => i.toLowerCase().trim())
    for (let i = 0; i < arrayB.length; i++) {
      if (conditionedArrayA .includes(arrayB[i].toLowerCase().trim())) {
        ret.push(arrayB[i].toLowerCase().trim());
      }
    }
    return returnArray;
  }

Which returns: "salt", "orange" quite happily; the problem being that it can't see "pepper" in arrayA because it has "cracked black" in front of it.

How do i get it to search anywhere inside each string of the conditioned arrayA?

Thanks

2
  • The title of your question and the problem description in your body are at odds. "Cracked Black Pepper" is not a substring of "pepper", but ignoring case sensitivity, "pepper" is a substring of "Cracked Black Pepper". Was your question intended to be "filter two arrays where array B contains any substring of A"? Commented Mar 14, 2019 at 17:18
  • Good point, changed it Commented Mar 14, 2019 at 17:24

3 Answers 3

4

You can use filter and some. with regex

  • Filter is used to get desired values only.
  • Some is used to check if any of values in arrayA matches with current element.
  • Regex is used to match the string. i flag is used for case insensitivity.

let arrayA = ["apples", "Oranges", "salt", "Cracked Black Pepper"];
let arrayB = ["salt", "pepper", "orange"]

let find = (A,B) => {
  return B.filter(b=> A.some(a=> new RegExp(b,'i').test(a)))
}

console.log(find(arrayA,arrayB))

Sign up to request clarification or add additional context in comments.

1 Comment

Just a side note, make sure that your arrays aren't strings that come from user input in any way. If they are, use this for escaping the strings before passing them to the RegExp constructor or you'll end up with a vulnerability.
1

Since arrayB contains the "needles", and arrayA contains the "haystacks", so to speak, you can use String.prototype.includes(). Note you are actually using Array.prototype.includes() in your attempt, which is why it only matches "salt" (based on your example code, I am highly doubtful that even "orange" was a successful match).

Below is a solution that uses String.prototype.includes() instead:

function matchedSubstrings (haystacks, needles) {
  return needles.filter(function (needle) {
    const lowerCaseNeedle = needle.toLowerCase()
    return this.some(haystack => haystack.includes(lowerCaseNeedle))
  }, haystacks.map(haystack => haystack.toLowerCase()))
}

const arrayA = ["apples", "Oranges", "salt", "Cracked Black Pepper"]
const arrayB = ["Salt", "pepper", "orange"]

console.log(matchedSubstrings(arrayA, arrayB))

The this of the Array.prototype.filter() callback function is the transformed haystacks array passed as the second argument.

The equivalent TypeScript is as follows:

function matchedSubstrings (haystacks: string[], needles: string[]): string[] {
  return needles.filter(function (this: string[], needle) {
    const lowerCaseNeedle = needle.toLowerCase()
    return this.some(haystack => haystack.includes(lowerCaseNeedle))
  }, haystacks.map(haystack => haystack.toLowerCase()))
}

const arrayA = ["apples", "Oranges", "salt", "Cracked Black Pepper"]
const arrayB = ["Salt", "pepper", "orange"]

console.log(matchedSubstrings(arrayA, arrayB))

Comments

0

let arrayA = ["apples", "Oranges", "salt", "Cracked Black Pepper"];
let arrayB = ["salt", "pepper", "orange"]

let find = (A,B) => {
  return B.filter(b=> A.some(a=> new RegExp(b,'i').test(a)))
}

console.log(find(arrayA,arrayB))

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.