Javascript Строка включает точное совпадение без дальнейших совпадений - PullRequest
1 голос
/ 09 марта 2020

все еще учится JS и столкнулся с этой проблемой, что я не был полностью уверен, как подойти, так что, надеюсь, кто-то может помочь мне вести меня в этом направлении. У меня есть массив изображений продуктов, каждое из которых содержит строку 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"} 
]

У меня также есть массив всех возможных цветов (которые в настоящее время я не использую в своем logi c), но он доступен:

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

Я пытаюсь проверить каждое изображение в массиве images, если текст alt содержит заданный цвет, а затем создать запись цвета в этом объекте с данным цветом.

ie. если строка "A Red Heather Jacket" содержит экземпляр "Red Heather", создайте запись color: "Red Heather" в этом объекте.

Где я нахожусь на

У меня есть рабочая функция, где я перебираю массив изображений и использую .include () , чтобы проверить, в строке alt есть совпадение. Это работает, когда возможный цвет совпадения составляет два слова (ie. "Red Heather") и совпадает с этими двумя словами в строке, но когда я использую что-то вроде "Red", тогда он будет соответствовать "Red" AND "Red Heather". Я пытаюсь выяснить, есть ли какой-нибудь способ, которым я мог бы заставить "Красный" просто соответствовать "Красному", а не в других случаях, когда красный упоминается в более длинном цвете?

Ниже приведена функция, которая работает для возможного совпадения "Red Heather", но не для «красного» * ​​1030 *

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);

Возвращает

[
  { 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" }
]

Ожидаемый результат для 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" }
]

Дайте мне знать, если есть другие способы решения этой проблемы, я думал разбить его на массив или использовать match () с регулярным выражением, но не знаю, где go отсюда.

Ответы [ 2 ]

1 голос
/ 09 марта 2020

У меня также есть массив всех возможных цветов (которые я сейчас не использую в своей логике c), но он доступен:

Я думаю, что это проблема. Если в некоторых элементах есть подстроки других элементов, и вы хотите, чтобы только другой элемент соответствовал, если он существует во входных данных, то необходимо включить проверку того, что цвет, который вы ищете это единственный, который существует на входе. Используйте .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);

Если, как вы упомянули, вы хотите использовать регулярное выражение, удалите индекс 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);
0 голосов
/ 09 марта 2020

Может быть, вы хотите сделать, как:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...