0

So I am playing around trying to build an input that I can type and then show only the objects that have matching text. I am getting close but need a little help. I think what I did works but I believe there might be a better way.

So I would expect that a user, in the input could type the following values:

  • phone
  • email
  • firstName
  • lastName
  • firstName lastName

I think the code I have works for it all, but not sure I like what I did for first and last name. I wonder if I should be using regex instead of what I am doing. Thoughts?

export let customers = [
  {
    id: 1,
    firstName: 'John',
    lastName: 'Smith',
    email: '[email protected]',
    phone: '7025551234',
  },
  {
    id: 2,
    firstName: 'Jonathan',
    lastName: 'Harken',
    email: '[email protected]',
    phone: '7165551234',
  },
  {
    id: 3,
    firstName: 'Zack',
    lastName: 'Moss',
    email: '[email protected]',
    phone: '9995551234',
  },
];

export const filterList = (suggestions, searchValue) => {
  return suggestions.filter((sug) => {
    let shouldReturn = false;

    for (const [key, keyValue] of Object.entries(sug)) {
      if (key !== 'id') {
        let keyV = keyValue.toLowerCase();
        let hasSpace = searchValue.indexOf(' ') > -1;

        if (!hasSpace && keyV.indexOf(searchValue) > -1) {
          shouldReturn = true;
        }

        if (hasSpace) {
          let split = searchValue.split(' ');

          switch (key) {
            case 'firstName':
              if (keyV.indexOf(split[0]) > -1) {
                shouldReturn = true;
              }

              break;
            case 'lastName':
              if (keyV.indexOf(split[1]) > -1) {
                shouldReturn = true;
              }

              break;
            default:
              break;
          }
        }
      }
    }

    if (shouldReturn) {
      return sug;
    } else {
      return null;
    }
  });
}

I just think something is off.

enter image description here

1
  • indexOf to look for static pieces of text is perfectly fine. Only improvement I could see a regular expression bringing here, is that you can make the whole search case-insensitive by just setting the according flag. (But that’s something you can have with indexOf as well, if you lowercase both input text and search value first.) Commented Oct 28, 2020 at 12:10

1 Answer 1

1

This is simpler version should behave like your function.

let customers = [{
    id: 1,
    firstName: 'John',
    lastName: 'Smith',
    email: '[email protected]',
    phone: '7025551234',
},
{
    id: 2,
    firstName: 'Jonathan',
    lastName: 'Harken',
    email: '[email protected]',
    phone: '7165551234',
},
{
    id: 3,
    firstName: 'Zack',
    lastName: 'Moss',
    email: '[email protected]',
    phone: '9995551234',
},
];


function filterByValue(objectList, searchValue) {

    const tokens = searchValue.toLowerCase().split(' ');

    return Object.values(objectList).filter(entry => {
        return Object.values(entry).some(entryValue => {

            if (typeof(entryValue) !== 'string')
                return false;
            
                entryValue = entryValue.toLowerCase();

            return tokens.every(token => entryValue.includes(token));
        })
    })
}

console.log(filterByValue(customers, '.com'))
console.log(filterByValue(customers, '555 234'))
console.log(filterByValue(customers, 'John 555'))
console.log(filterByValue(customers, 'John test .com'))

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

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.