找出字符串数组和由该数组生成的字符串之间的区别-React Native



所以这是我面临的一个有趣的问题。我有一个从ASR服务器接收的数组,格式如下[{start: 0, end: 0.4, word: "Hello"}, {start: 0.4, end: 0.6, word: "my"}, {start: 0.6, end: 1, word: "name"}]。然后将该数组映射到仅包含单词(例如["Hello", "my", "name"](的字符串数组,最后使用.join(" ")将该数组转换为字符串,从而产生类似于该"Hello my name"的字符串。

问题是试图编辑这些值并保持原始数组的格式。我使用React Native TextInput来编辑字符串值。

假设用户想要更改

"你好,我的名字">

"你好,我的名字叫">

"贝娄我的名字">

在第一种情况下,需要将阵列调整为[{start: 0, end: 0.4, word: "Hello"}, {start: 0.4, end: 0.6, word: "my"}, {start: 0.6, end: 1, word: "name is"}],在第二种情况下必须将阵列调整至[{start: 0, end: 0.4, word: "Bellow"}, {start: 0.4, end: 0.6, word: "my"}, {start: 0.6, end: 1, word: "name"}]

我完全不知道该如何处理这件事。我已经做了大约两个星期了,但仍然不知道。我最近的尝试是通过原始数组进行映射,将每个项目的单词值与同一索引处编辑过的字符串的单词进行比较。如果它们匹配,我会将它们添加到最终数组中,如果不匹配,我将检查编辑后的字符串中的值是否与我从Lodash.js中的.difference()函数中得到的更改之一匹配。我可能解释得不好,所以请查看代码。

const [value, setValue] = useState('');
const findChanges = () => {
let finalWords = [];
// Each of the elements in the currentWords array has three properties: start, end, word
let currentWords = data.words;
if (!Array.isArray(currentWords)) currentWords = JSON.parse(data.words);
// Extract only word strings from currentWords
let currentArr = currentWords.map(x => x.word);
let newArr = value.split(' ');
let currentChangeEndsAt = undefined;
let diff = difference(newArr, currentArr);
const addToFinal = (text: string, startIndex: number, endIndex: number) => {
if (startIndex === endIndex) {
return finalWords.push({ ...currentWords[startIndex], word: text });
}
let start = currentWords[startIndex].start;
let end = currentWords[endIndex].end;
return finalWords.push({ start, end, word: text });
};
currentArr.forEach((word, index) => {
// If index is smaller then we have already handled this word, skip
if (currentChangeEndsAt > index) {
return;
}
// If currentArr item at index matches newArr item at same index, add word to final
if (word === newArr[index]) {
return addToFinal(word, index, index);
}
// If currentArr item at index is one of the the differences
if (diff.indexOf(word) !== -1) {
// Determine recursively at which index the change ends
const changeEndsAt = (searchIndex): number => {
// If next word in currentArr matches the word in newArr at searchIndex return searchIndex
// Else add 1 to searchIndex and recursively call the func again
if (currentArr[index + 1] === newArr[searchIndex]) {
return searchIndex;
} else if (searchIndex === newArr.length - 1) {
return searchIndex;
} else {
return changeEndsAt(searchIndex + 1);
}
};
// Get substring of the change
const endsAt = changeEndsAt(index + 1);
const changeString = newArr.slice(index, endsAt).join(' ');
const endIndex =
endsAt > currentWords.length - 1 ? currentWords.length - 1 : endsAt;
return addToFinal(changeString, index, endIndex);
}
});
return finalWords;
};

正如你所看到的,这是一个相当混乱的局面,你可能可以看出,由于几个原因,它不会起作用。其中一个原因是,如果在字符串的开头添加一个单词,函数就会崩溃。我曾想过可能实现一个onChangeText处理程序,并可能使用onSelectionChange回调设置TextInput的当前光标位置,但我还没能弄清楚如何从那里开始。如果有人能告诉我如何处理这件事,甚至从哪里开始,那将非常有帮助。我为冗长的问题和模糊的标题道歉,我愿意接受关于改进这两个问题的建议。如果你有更好的想法,请在下面评论。提前谢谢。

如果我理解正确,您可以简单地将字符串拆分为组件;第一分量与{ start: 0, end: 0.4 }组合,第二分量与{ start: 0.4, end: 0.6 }组合,并且第二分量之外的所有分量通过空格连接并与{ start: 0.6, end: 1 }组合。

let inp = document.querySelector('input');
let code = document.querySelector('code');
let fn = () => {

let input = inp.value;
let [ cmp1='', cmp2='', ...cmps ] = input.split(' ');
let output = [
{ start: 0, end: 0.4, word: cmp1 },
{ start: 0.4, end: 0.6, word: cmp2 },
{ start: 0.6, end: 1, word: cmps.join(' ') }
];
code.textContent = ''
+ '[n'
+ output.map(item => '  ' + JSON.stringify(item)).join(',n')
+ 'n]'

};
inp.addEventListener('input', fn);
fn();
code { white-space: pre; }
<p>Edit this text:</p>
<input value="Hello my name"/><br/>
<code></code>

我不确定我是否完全理解你的问题。如果这不是你想要的,请举一个产生无效输出的输入的例子,以及在该场景中正确的输出应该是什么

最新更新