3

var myArray = [
    ["good morning", "am", "morning"],
    ["good night", "night", "evening"],
    ["good day", "day is good", "it's a good day"]
];

function compare(entry, string) {
    for (var x in entry) {
        strings = string.split(' ');
        array1 = entry[x][0].split(' ');
        if (strings.every(s => array1.indexOf(s) !== -1)) {
            items = entry[x].slice(1);
            return items
        } else {
            //return 'not found'
        }
    }
}
$("#input").keydown(function(e) {
    keyword = $(this).val();
    if (e.which === 13) {
        $(this).val("");
        text = keyword.toLowerCase();
        result = '<div>' + compare(myArray, text) + '</div>'
        $('#results').append(result);
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="input" type="text" placeholder="Search..." autocomplete="off" />
<div id="results" class="reset"></div>

strings = Keywords from input box is converted into an array

array1 = Each first items from group of arrays are converted into an array

...compare them then return items from the same group where it found the matched keywords. I used .slice(1) so it wont return the first item of each group.

Using every() is the closest iv got after trying includes(), .some() etc...

I have two problems on the above code:

  1. it will return undefined if the keyword is more than the words present in the array.

it should return true if keywords are:

good,

good morning dude,

good night folks,

good day people

  1. if I put "else" on the condition, it wont function same as without "else"...

thanks for your help..

3
  • have you considered String.prototype.includes rather than parsing out individual words? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Oct 29, 2020 at 1:35
  • it will return undefined if the keyword is not present in the array. what should be the default return value in this case then? Commented Oct 29, 2020 at 1:40
  • it should still return true if it found at least one word. Commented Oct 29, 2020 at 2:07

2 Answers 2

1

Use .map() twice, see if the string is included in the inner array value, then flatten the array and filter out non-string values.

This code finds matching words in each string. The ternary either returns the string (if found) or returns null if not found. That gives an array of arrays. So they get flattened into a single array. Finally, the null values are filtered out.

here is one way to accomplish your goal:

var myArray = [
  ["good morning", "am", "morning"],
  ["good night", "night", "evening"],
  ["good day", "day is good", "it's a good day"]
];

function compare(entry, string) {
  let out = string
             .split(' ')
             .map(str => 
                   entry.map(e => 
                          e.map(f => (f.includes(str)) ? f : null))
              .flat()
              .filter(a => a !== null));
  return out.join(', ');
}

compare(myArray, 'good night dude');

$("#input").keydown(function(e) {
  keyword = $(this).val();
  if (e.which === 13) {
    $(this).val("");
    text = keyword.toLowerCase();
    result = '<div>' + compare(myArray, text) + '</div>'
    $('#results').append(result);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="input" type="text" placeholder="Search..." autocomplete="off" />
<div id="results" class="reset"></div>

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

5 Comments

looks good but it did not solved problem #1, for example >> "good night dude" .
ah - see my edit. This will find any singular search term that matches any singular term in the string of the array, and return the entire matched string.
can we return the most relevant result on top? the original code does that.
I realize that in your mind your requirements are crystal clear. But, your question lacks clarity (for me). For instance, there is no definition of what you expect "the most relevant result" to be. What would it be for a search string such as "dude, tonight, this evening is a good night and I cannot wait until a good morning"
i also forgot to mention that >> I used .slice(1) so it wont return the first item of each group.
0

Return some value that represents "not found" and check in keydown() function before appending the text to div

var myArray = [
    ["good morning", "am", "morning"],
    ["good night", "night", "evening"],
    ["good day", "day is good", "it's a good day"]
];

function compare(entry, string) {
    for (var x in entry) {
        strings = string.split(' ');
        array1 = entry[x][0].split(' ');
        if (strings.every(s => array1.indexOf(s) !== -1)) {
            items = entry[x].slice(1);
            return items
        } else {
            return -1;
        }
    }
}
$("#input").keydown(function(e) {
    keyword = $(this).val();
    if (e.which === 13) {
        $(this).val("");
        text = keyword.toLowerCase();
        var matched = compare(myArray, text);
        if(matched!=-1){
          result = '<div>' + matched + '</div>'
        } else {
          result = '<div>Not Found</div>'
        }
       
        $('#results').append(result);
    }
});

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.