1

I am building a mini search engine on my website that can search for words and has filters.

I need to be able to take a long string, and split it up into an array of smaller substrings. The words (with no filter) should go in one string, and then each filter should go in a separate string. The order of words and filters should not matter.

For example:

If my string is:

"hello before: 01/01/17 after: 01/01/2015"

OR:

"before: 01/01/17 hello after: 01/01/2015"

I would expect my function to return (in any order):

["hello", "before: 01/01/2017", "after: 01/01/2015"]

1
  • I figured out how to solve this when the word is before any of the filters, but I'm having trouble splitting up the string if the word is in the middle/end of the string Commented Jan 30, 2017 at 21:16

2 Answers 2

1

You could use whitespace and a positive lookahead for splitting.

console.log("hello before: 01/01/17 after: 01/01/2015".split(/\s*(?=before|after)/));

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Nina. Your solution worked great originally, but now I'm trying to solve the problem where the order of words doesn't matter.
you could omit the space after : and then split by space and check then the type of the part.
0

Are there any specific limitations for code size? I mean, this isn't code-golf or anything, so why not just do it the straight-forward way?

First, you can tokenize this with a simple regular expression

var search_string = "hello before: 01/01/17 after: 01/01/2015";
var regex = /(?:(before|after)\:\s*)?([^ ]*)/g
var token = null;
while ((token = regex.exec(search_string)) != null) {

Then, you can put the arrange them into any data structure you want. For example, we can put the filters into a separate object, as so:

var filters = {};
var words = [];
//...
    if (token[1])
        filters[token[1]] = token[2];
    else
        words.push(token[2]);

After that, you can manipulate these structures any way you want

words.sort();
if (filters['before']) words.push(filters['before']);
if (filters['after']) words.push(filters['after']);
return words;

I'm not sure why you'd want it arranged this way, but this would make things uniform. Alternately, you can use them in a more straightforward way:

var before = Date.parse(filters['before'] || '') || false;
if (before !== false) before = new Date(before);
var after = Date.parse(filters['after'] || '') || false;
if (after !== false) before = new Date(before);
function isDocumentMatchSearch(doc) {
    if (before !== false && doc.date > before) return false;
    if (after !== false && doc.date < after) return false;
    for (var i = 0; i < words.length; i++) {
        if (doc.title.indexOf(words[i]) < 0 &&doc.text.indexOf(words[i]) < 0) return false;
    }
    return true;
}

Since you didn't give a lot of information on what you're searching through, what data types or storage type it's stored in, etc etc, that's the best I can offer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.