@campus1

Как найти в строке первый уникальный символ без учёта регистра?

Есть задача найти первый уникальный символ в строке.

Я сделал так:

const firstNonRepeatingLetter = str => {
  let charMap = {};
  let strToLower = str.toLowerCase();
  for (let char of strToLower) {
    if (!charMap[char]) {
      charMap[char] = 1;
    } else {
      charMap[char]++;
    }
  }

  for (let char in charMap) {
    if (charMap[char] === 1) {
      return char;
    }
  }
  return '';
};

Но один тест не проходит, потому что на вход передается "sTreSS" и должно вернутся "T", а у меня "t". Что надо поправить?
  • Вопрос задан
  • 250 просмотров
Решения вопроса 2
twobomb
@twobomb
Ну если не переписывая код, а добавляя то так
const firstNonRepeatingLetter = str => {
  let charMap = {};
  let strToLower = str.toLowerCase();
  for (let char of strToLower) {
    if (!charMap[char]) {
      charMap[char] = 1;
    } else {
      charMap[char]++;
    }
  }

  for (let char in charMap) {
    if (charMap[char] === 1) {
      var i = str.indexOf(char);
      if( i == -1)
        i = str.indexOf(char.toUpperCase())
      else if(str.indexOf(char.toUpperCase()) != -1 && str.indexOf(char.toUpperCase()) < i)
        i = str.indexOf(char.toUpperCase());
      return str.charAt(i);
    }
  }
  return '';
};

P.S. А вообще можно немного короче сделать
function firstNonRepeatingLetter(str) {
  for(var i = 0 ; i < str.length;i++)
  if((str.substring(0,i)+str.substring(i+1)).indexOf(str.charAt(i).toLowerCase()) == -1 && (str.substring(0,i)+ str.substring(i+1)).indexOf(str.charAt(i).toUpperCase()) == -1)
      return str.charAt(i);
	return '';
}

Хотя я уверен что можно еще короче
Ответ написан
0xD34F
@0xD34F Куратор тега JavaScript
Считаем повторения символов, приведённых к нижнему регистру, также, встречая символ впервые, запоминаем индекс и оригинальный вид символа (до приведения к нижнему регистру); ищем среди результатов подсчёта повторений такой, который равен единице, и при этом имеет минимально возможный индекс; достаём из найденного оригинальный символ:

const firstNonRepeatingLetter = ([...str]) => Object
  .values(str.reduce((acc, n, i) => ((acc[n.toLowerCase()] ??= [ 0, i, n ])[0]++, acc), {}))
  .reduce((min, n) => (n[0] === 1 && n[1] < min[1] ? n : min), [ 0, Infinity, '' ])
  .pop();

Или. Приводим строку к нижнему регистру; ищем индекс первого уникального символа, т.е. такого, у которого индекс первого вхождения в строку равен индексу последнего вхождения; по найденному индексу извлекаем из исходной строки символ:

const firstNonRepeatingLetter = str =>
  str.charAt(Array
    .from(str.toLowerCase())
    .findIndex((n, i, a) => a.indexOf(n) === a.lastIndexOf(n))
  );
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы