Skip to content

Instantly share code, notes, and snippets.

@Announcement
Last active May 28, 2018 01:50
Show Gist options
  • Save Announcement/c079eb3b30f0668ef2a86283d3e74a4b to your computer and use it in GitHub Desktop.
Save Announcement/c079eb3b30f0668ef2a86283d3e74a4b to your computer and use it in GitHub Desktop.
search lists of text.
function replaceSelection(newString, oldString, stringIndex, stringLength) {
return oldString.substring(0, stringIndex) + newString + oldString.substring(stringIndex + stringLength)
}
function compile2({ source, sourceMap }, transform) {
const generatedMap = new Map()
let offset = 0
let currentRelativePosition = 0
let generated = `${source}`
for (const { index, length, data } of getSourceMapEntries(sourceMap)) {
const replacement = transform(data, currentRelativePosition++)
const difference = replacement.length - length
if (generated.substr(offset + index, length) !== source.substr(index, length)) {
console.warn('String or sourcemap has been corrupted.', { offset, index, difference, length, source, sourceMap } )
}
setSourceMapData(generatedMap, offset + index, replacement)
generated = replaceSelection(replacement, generated, offset + index, length)
offset += difference
}
return {
generated,
generatedMap
}
}
function setSourceMapData (map, index, data) {
const length = data.length
if (!map.has(index)) map.set(index, new Map())
if (!map.get(index).has(length)) map.get(index).set(length, new Set())
map.get(index).get(length).add(data)
}
function* getSourceMapEntries (map) {
for (const [index, indexes] of map)
for (const [length, lengths] of indexes)
for (const data of lengths)
yield { index, length, data }
}
function parse (source, them) {
const sourceMap = new Map()
for (let i = 0; i < them.length; i++) {
const match = them[i]
setSourceMapData(sourceMap, match.index, match.text)
}
return { source, sourceMap }
}
function * getIndexes (subject, content) {
for (let index = 0; (index = content.indexOf(subject, index)) !== -1; index += subject.length)
yield index
}
var a = performance.now()
var results = [...search(moviesJson.map(movie => movie.title), 'abc')]
var b = performance.now()
var html = results
.map(([a, b]) => { return [a, b.map(it => { return { index: it, length: 1, text: a.substring(it, it + 1) } })] })
.map(([source, them]) => parse(source, them))
.map(it => `<pre style="font-size:24px">` + compile2(it, x => `<b style="text-decoration:underline">${x}</b>`).generated + `</pre>`)
.join('\n')
console.log(`found ${results.length} results in ${b - a} milliseconds.`)
$$.html(html)
function * search (dataset, query) {
const $query = query.toLowerCase()
for (const entry of dataset) {
const positions = []
const $entry = entry.toLowerCase()
for (const character of $query) {
positions.push([...getIndexes(character, $entry)])
}
if (positions.every(position => position.length > 0)) {
const endex = positions.reduce((previous, current, index, array) => {
if (index === 1) {
return [previous[0], current.find(it => it > previous[0])]
}
if (previous[previous.length - 1] === undefined || previous[previous.length - 1] === null) {
return previous
}
return [ ...previous, current.find(it => it > previous[previous.length - 1]) ]
})
if (endex[endex.length - 1] !== undefined && endex[endex.length - 1] !== null) {
yield [entry, endex]
}
}
}
}
function * getIndexes (subject, content) {
for (let index = 0; (index = content.indexOf(subject, index)) !== -1; index += subject.length)
yield index
}
[...search(['microsoft edge', 'mozilla firefox', 'internet explorer'], 'ie')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment