简体   繁体   English

Javascript 字符串包括没有进一步匹配的完全匹配

[英]Javascript String Includes Exact Match without further matches

still learning JS and came across this issue that I was not fully sure how to approach so hopefully someone can help lead me in the direction.仍在学习 JS 并遇到了这个我不完全确定如何处理的问题,所以希望有人能帮助我找到方向。 I have an array of product images each containing an alt string with the color referenced somewhere in it like this我有一组产品图像,每个图像都包含一个alt字符串,其中的颜色在其中的某处引用,如下所示

let images = [
  {id:1, alt:"A Red Jacket"},
  {id:2, alt:"A Red Heather Jacket"},
  {id:3, alt:"Picture of Red Heather Awesome Jacket"} 
]

I also have an array of all possible colors (which I am not currently using in my logic) but have it available:我还有一个包含所有可能颜色的数组(我目前没有在我的逻辑中使用它)但是可以使用它:

let colorOptions = ["Red", "Red Heather", "Blue", "Soft Red"]

I'm trying to check for each image in the images array if the alt text includes a given color, then create a color entry in that object with the given color.如果alt文本包含给定颜色,我正在尝试检查images数组中的每个图像,然后使用给定颜色在该对象中创建一个颜色条目。

ie. IE。 if "A Red Heather Jacket" string contains an instance of "Red Heather" then create a color: "Red Heather" entry in that object.如果"A Red Heather Jacket"字符串包含"Red Heather"的实例,则在该对象中创建一个color: "Red Heather"条目。

Where I am at我在哪里

I have a working function where I am looping through the images array and using .includes() to check if there is a match in the alt string.我有一个工作函数,我循环遍历图像数组并使用.includes()检查 alt 字符串中是否存在匹配项。 It works for when the possible match color is two words (ie. "Red Heather" ) and matches those two words in the string, but when I use something like "Red" then it will match "Red" AND "Red Heather" .它适用于当可能的匹配颜色是两个单词(即"Red Heather" )并匹配字符串中的这两个单词时,但是当我使用诸如"Red"类的东西时,它将匹配"Red" AND "Red Heather" Im trying to figure out if there is any way I could get "Red" to just match "Red" and not other instances where red is mentioned in the longer color?我想弄清楚是否有任何方法可以让“红色”只匹配“红色”而不是其他在较长颜色中提到红色的实例?

Below is the function that works for a possible match "Red Heather" but doesn't for "Red"以下是适用于可能匹配"Red Heather"但不适用于“Red”的功能

let images = [
  { id: 1, alt: "A Red Jacket" },
  { id: 2, alt: "A Red Heather Jacket" },
  { id: 3, alt: "A Red Heather Awesome Jacket" }
];

//not using the below array but think it could help
let colorOptions = ["Red", "Red Heather", "Blue"];

function findMatch(array, match) {
  for (var i = 0; i < array.length; i++) {
    if (array[i].alt.includes(match)) {
      array[i].color = match;
    }
  }

  return array;
}

let redHeather = findMatch(images, "Red");
console.log(redHeather);

Returns退货

[
  { id: 1, alt: "A Red Jacket" , color: "Red" },
  { id: 2, alt: "A Red Heather Jacket", color: "Red" },
  { id: 3, alt: "A Red Heather Awesome Jacket", color: "Red" }
]

Expected Result for findMatch(images, "Red") findMatch(images, "Red")预期结果

[
  { id: 1, alt: "A Red Jacket" , color: "Red" },
  { id: 2, alt: "A Red Heather Jacket" },
  { id: 3, alt: "A Red Heather Awesome Jacket" }
]

Let me know if there are some other ways to approach this, I have thought of breaking it up into an array or using match() with regex but unsure where to go from here.让我知道是否有其他方法可以解决这个问题,我曾想过将其分解为一个数组或将match()与正则表达式一起使用,但不确定从哪里开始。

I also have an array of all possible colors (which I am not currently using in my logic) but have it available:我还有一个包含所有可能颜色的数组(我目前没有在我的逻辑中使用它)但是可以使用它:

I think that's the problem.我认为这就是问题所在。 If some of the items there are substrings of other items, and you'd want only the other item to match if it exists in the input, then you need to include a check that the color you're looking for is the only one that exists in the input.如果某些项目有其他项目的子字符串,并且您希望其他项目匹配(如果它存在于输入中),那么您需要检查您正在寻找的颜色是唯一的颜色存在于输入中。 Use .every to check that for every item in colorOptions , it's either the match argument, or it's not included in the alt :使用.every检查在每一个项目colorOptions ,这是无论是match的说法,或者它不包括在alt

 let images = [ { id: 1, alt: "A Red Jacket" }, { id: 2, alt: "A Red Heather Jacket" }, { id: 3, alt: "A Red Heather Awesome Jacket" } ]; let colorOptions = ["Red", "Red Heather", "Blue"]; function findMatch(array, match) { for (const item of array) { if ( item.alt.includes(match) && colorOptions.every(color => color === match || !item.alt.includes(color)) ) { item.color = match; } } return array; } let redHeather = findMatch(images, "Red"); console.log(redHeather);

If, like you mentioned, you want to use a regex, remove the match index in the array, then pass to new RegExp :如果,就像你提到的,你想使用一个正则表达式,删除数组中的match索引,然后传递给new RegExp

 let images = [ { id: 1, alt: "A Red Jacket" }, { id: 2, alt: "A Red Heather Jacket" }, { id: 3, alt: "A Red Heather Awesome Jacket" } ]; let colorOptions = ["Red", "Red Heather", "Blue"]; function findMatch(array, match) { const index = colorOptions.indexOf(match); const newArr = colorOptions.slice(0, index).concat(colorOptions.slice(index + 1)); const pattern = new RegExp(newArr.join('|')); for (const item of array) { if (item.alt.includes(match) && !pattern.test(item.alt)) { item.color = match; } } return array; } let redHeather = findMatch(images, "Red"); console.log(redHeather);

Maybe you want to do like:也许你想做:

 const images = [ { id: 1, alt: "A Red Jacket" }, { id: 2, alt: "A Red Heather Jacket" }, { id: 3, alt: "A Red Heather Awesome Jacket" } ]; function JacketMatcher(array){ // I now prefer constructors over classes since you can have private variables where you don't have to write `this.` on properties you don't want public anyways this.match = match=>{ const a = array.slice(), rx = new RegExp('^A\\\\s+'+match+'\\\\s+Jacket$'); for(let i=0,o,v,l=a.length; i<l; i++){ o = {}; v = a[i]; for(let k in v){ o[k] = v[k]; } if(o.alt.match(rx))o.color = match; a[i] = o; } return a; } } const jm = new JacketMatcher(images); const justRed = jm.match('Red'); console.log(justRed); const redHeather = jm.match('Red Heather'); console.log(redHeather);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM