Создать функцию, которая принимает строку и группирует повторяющиеся значения - PullRequest
2 голосов
/ 07 ноября 2019

Создать функцию, которая принимает строку и группирует повторяющиеся значения. Группы должны иметь следующую структуру: [[value, first_index, last_index, times_repeated], ..., [value, first_index, last_index, times_repeated]].

  • значение: Оцениваемый символ.
  • first_index: Индекс первого появления символов.
  • last_index: Индекс последнего появления символов.
  • times_repeated: Количество повторений символов подряд.

Примеры

findRepeating("a") ➞ [["a", 0, 0, 1]]

findRepeating("aabbb") ➞ [["a", 0, 1, 2], ["b", 2, 4, 3]]

findRepeating("1337") ➞ [["1", 0, 0, 1], ["3", 1, 2, 2], ["7", 3, 3, 1]]

findRepeating("aabbbaabbb") ➞ [["a", 0, 1, 2], ["b", 2, 4, 3], ["a", 5, 6, 2], ["b", 7, 9, 3]]

Я могу сделать это для уникальных символов. Но не может сделать это в течение

Количество повторений символов подряд

МОЙ КОД

function findRepeating(str) {
    let unique = [...new Set([...str])]
    return unique.map(x=>[x,str.indexOf(x),str.lastIndexOf(x),[...str].filter(a=>a==x).length])
}

ОЖИДАЕМЫЙ РЕЗУЛЬТАТ

Test.assertSimilar(findRepeating(''), [])
Test.assertSimilar(findRepeating('a'), [['a', 0, 0, 1]])
Test.assertSimilar(findRepeating('1337'), [['1', 0, 0, 1], ['3', 1, 2, 2], ['7', 3, 3, 1]])
Test.assertSimilar(findRepeating('aabbb'), [['a', 0, 1, 2], ['b', 2, 4, 3]])
Test.assertSimilar(findRepeating('addressee'), [['a', 0, 0, 1], ['d', 1, 2, 2], ['r', 3, 3, 1], ['e', 4, 4, 1], ['s', 5, 6, 2], ['e', 7, 8, 2]])
Test.assertSimilar(findRepeating('aabbbaabbb'), [['a', 0, 1, 2], ['b', 2, 4, 3], ['a', 5, 6, 2], ['b', 7, 9, 3]])
Test.assertSimilar(findRepeating('1111222233334444'), [['1', 0, 3, 4], ['2', 4, 7, 4], ['3', 8, 11, 4], ['4', 12, 15, 4]])
Test.assertSimilar(findRepeating('1000000000000066600000000000001'), [['1', 0, 0, 1], ['0', 1, 13, 13], ['6', 14, 16, 3], ['0', 17, 29, 13], ['1', 30, 30, 1]])

АКТУАЛЬНЫЙ РЕЗУЛЬТАТ

Test Passed: Value == '[]'
Test Passed: Value == "[['a', 0, 0, 1]]"

Test Passed: Value == "[['1', 0, 0, 1], ['3', 1, 2, 2], ['7', 3, 3, 1]]"
Test Passed: Value == "[['a', 0, 1, 2], ['b', 2, 4, 3]]"
FAILED: Expected: "[['a', 0, 0, 1], ['d', 1, 2, 2], ['r', 3, 3, 1], ['e', 4, 4, 1], ['s', 5, 6, 2], ['e', 7, 8, 2]]", instead got: "[['a', 0, 0, 1], ['d', 1, 2, 2], ['r', 3, 3, 1], ['e', 4, 8, 3], ['s', 5, 6, 2]]"
FAILED: Expected: "[['a', 0, 1, 2], ['b', 2, 4, 3], ['a', 5, 6, 2], ['b', 7, 9, 3]]", instead got: "[['a', 0, 6, 4], ['b', 2, 9, 6]]"
Test Passed: Value == "[['1', 0, 3, 4], ['2', 4, 7, 4], ['3', 8, 11, 4], ['4', 12, 15, 4]]"
FAILED: Expected: "[['1', 0, 0, 1], ['0', 1, 13, 13], ['6', 14, 16, 3], ['0', 17, 29, 13], ['1', 30, 30, 1]]", instead got: "[['1', 0, 30, 2], ['0', 1, 29, 26], ['6', 14, 16, 3]]"

function findRepeating(str) {
	let unique = [...new Set([...str])]
	return unique.map(x=>[x,str.indexOf(x),str.lastIndexOf(x),[...str].filter(a=>a==x).length])
}
console.log("Fails   ",JSON.stringify(findRepeating('addressee')),"\nexpected", `[['a',0,0,1],['d',1,2,2],['r',3,3,1],['e',4,4,1],['s',5,6,2],['e',7,8,2]]`)
console.log("Fails   ",JSON.stringify(findRepeating('aabbbaabbb')),"\nexpected", `[['a',0,1,2],['b',2,4,3],['a',5,6,2],['b',7,9,3]]`)
console.log("Passes  ",JSON.stringify(findRepeating('1111222233334444')),"\nexpected", `[['1',0,3,4],['2',4,7,4],['3',8,11,4],['4',12,15,4]]`)
console.log("Fails   ",JSON.stringify(findRepeating('1000000000000066600000000000001')),"\nexpected", `[['1',0,0,1],['0',1,13,13],['6', 14,16,3],['0',17,29,13],['1',30,30,1]]`)

Ответы [ 2 ]

1 голос
/ 07 ноября 2019

Вы можете взять массив из тех же символов с регулярным выражением, которое ищет символ и те же следующие элементы в группе, и отобразить требуемую информацию.

function findRepeating(string) {
    var i = -1;
    return (string.match(/(.)\1*/g) || []).map(s => [s[0], ++i, i += s.length - 1, s.length]);
}

console.log(findRepeating(""));           // []
console.log(findRepeating("a"));          // [["a", 0, 0, 1]]
console.log(findRepeating("aabbb"));      // [["a", 0, 1, 2], ["b", 2, 4, 3]]
console.log(findRepeating("1337"));       // [["1", 0, 0, 1], ["3", 1, 2, 2], ["7", 3, 3, 1]]
console.log(findRepeating("aabbbaabbb")); // [["a", 0, 1, 2], ["b", 2, 4, 3], ["a", 5, 6, 2], ["b", 7, 9, 3]]
0 голосов
/ 07 ноября 2019

В вашем коде предполагается, что каждая группа имеет свой символ. Как только у вас есть две группы с одним и тем же символом, такие вещи, как lastIndex, дадут неправильный результат.

Просто используйте простой цикл for.

function findRepeating(str) {
    let result = [];
    let start = 0;
    for (let i = 0; i < str.length; i++) {
        if (str[i] !== str[i+1]) {
            result.push([str[i], start, i, i-start+1]);
            start = i+1;
        }
    }
    return result;
}

console.log(findRepeating(''), [])
console.log(findRepeating('a'), [['a', 0, 0, 1]])
console.log(findRepeating('1337'), [['1', 0, 0, 1], ['3', 1, 2, 2], ['7', 3, 3, 1]])
console.log(findRepeating('aabbb'), [['a', 0, 1, 2], ['b', 2, 4, 3]])
console.log(findRepeating('addressee'), [['a', 0, 0, 1], ['d', 1, 2, 2], ['r', 3, 3, 1], ['e', 4, 4, 1], ['s', 5, 6, 2], ['e', 7, 8, 2]])
...