1

I have a data like this:

dictionary: [
  { mercury: 'MERC' },
  { venus: 'VEN' },
  { earth: 'EART' },
  { mars: 'MAR' },
  { jupiter: 'JUP' },
  { saturn: 'SAT' },
  { uranus: 'ANUS' },
  { neptune: 'NEP' },
  { pluto: 'PLUT' },
]

When a user types letters inside an input field like v, I want to show the closest similar string from the object, which would be 'VEN' for this, I have the following code:

let word = 'v'
let result = dictionary.find(d => {
  var str = Object.keys(d)[0]
  if (str.toLowerCase().indexOf(word.toLowerCase()) == 0) {
    return result = str
  }
})

This code works well, and result returns the found string. The problem is that when someone types m I only get MERC but I should get multiple results because mercury and mar both start with m.

Is there an way to do this with find, or other function?

5
  • 1
    If you're trying to implement autocomplete, see this jqueryui.com/autocomplete Commented Feb 15, 2018 at 13:15
  • 1
    This indexOf(word.toLowerCase()) == 0 should be indexOf(word.toLowerCase()) >= 0 Commented Feb 15, 2018 at 13:15
  • 1
    Define CLOSEST SIMILAR before doing anything else :) Is it string containing the substring as a whole, containing each character in substring, starting with substring, ending with it, both.. Commented Feb 15, 2018 at 13:19
  • You don't need to use jquery/UI for a simple autocomplete. Commented Feb 15, 2018 at 13:22
  • 1
    Also, it's 2018, who uses Jquery UI anymore.... Commented Feb 15, 2018 at 13:25

3 Answers 3

4

You could filter the array and use just the values.

var dictionary = dictionary = [{ mercury: 'MERC' }, { venus: 'VEN' }, { earth: 'EART' }, { mars: 'MAR' }, { jupiter: 'JUP' }, { saturn: 'SAT' }, { uranus: 'ANUS' }, { neptune: 'NEP' }, { pluto: 'PLUT' }],
    word = 'm',
    result = dictionary
        .filter(d => Object.keys(d)[0].toLowerCase().startsWith(word))
        .map(o => Object.values(o)[0]);

console.log(result)

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

2 Comments

Thanks for the answer, do you think this method is efficient if I have like 6K word in my json file? I was told filter exits on first find so if a user was to search for a word like 'human' then every letter typed would do a loop over all 6 entries. Is there a better (optimized) way to do this without using a database?
please add the real data structure to the question. for really fas access. i would use a simple for loop which is faster than any array method.
3

find returns only one value.

Use Object.values and filter

var search = "m";
search = search.toLowerCase();
var output = Object.values(dictionary).map(s => Object.values(s)[0].toLowerCase()).filter(s => s.indexOf(search) == 0);
console.log( output );

Demo

var dictionary = [{
    mercury: 'MERC'
  },
  {
    venus: 'VEN'
  },
  {
    earth: 'EART'
  },
  {
    mars: 'MAR'
  },
  {
    jupiter: 'JUP'
  },
  {
    saturn: 'SAT'
  },
  {
    uranus: 'ANUS'
  },
  {
    neptune: 'NEP'
  },
  {
    pluto: 'PLUT'
  },
];
var search = "m";
search = search.toLowerCase();
var output = Object.values(dictionary).map(s => Object.values(s)[0].toLowerCase()).filter(s => s.indexOf(search) == 0);
console.log( output );

Edit

To return in the original case, use toLowerCase before doing indexOf

var output = Object.values( dictionary ).map(
       s => Object.values( s )[0] ).filter(
         s => s.toLowerCase().indexOf( search ) == 0);

2 Comments

@Liam Sorry, but the link you have shared points to my answer itself. Didn't understood your point.
@Liam I think OP has mentioned because mercury and mar both start with m.
1

Using function filter to get your targets.

var dictionary = [
  { mercury: 'MERC' },
  { venus: 'VEN' },
  { earth: 'EART' },
  { mars: 'MAR' },
  { jupiter: 'JUP' },
  { saturn: 'SAT' },
  { uranus: 'ANUS' },
  { neptune: 'NEP' },
  { pluto: 'PLUT' }
];

let word = 'm';
let result = dictionary.filter(d => Object.values(d)[0].toLowerCase().indexOf(word) > -1)


 console.log(result)

If you want the values, use map function.

var dictionary = [
  { mercury: 'MERC' },
  { venus: 'VEN' },
  { earth: 'EART' },
  { mars: 'MAR' },
  { jupiter: 'JUP' },
  { saturn: 'SAT' },
  { uranus: 'ANUS' },
  { neptune: 'NEP' },
  { pluto: 'PLUT' }
];

let word = 'm';
let result = dictionary.filter(d => Object.values(d)[0].toLowerCase().indexOf(word) > -1)


 console.log(result.map((b) => Object.values(b)[0]))

1 Comment

what have you changed and why

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.