Home > Software engineering >  How to check if specific word present in nested array of objects
How to check if specific word present in nested array of objects

Time:10-19

I have a text input and send button for submitting the text that I have entered in input field. I have used react-mention library for hashtags. Now when user is entering text and if user type "#" then it shows available hashtags from data. I want to add a functionality, if hashtag is not present in data then I want to add that hashtag dynamically and make api call.

Hashtag data looks like:

const hashtagData = [
  { id: 0, display: "end" },
  { id: 1, display: "start" },
];

Once user has selected the preregistered hashtag and writing his own hashtag, text will look like:

"sample text for already present hashtag #end and manually entered #newHashtag  

Inside my onclick function of submit button, I've written this logic for checking newly entered hashtag:

let array = [];
newComment.split(" ").map((word) => {
  array.push(word.split("#")[1]);
});
var r = hashtagData.some((i) => i.display.includes(array.map((j) => j)));
console.log(r);

I am not sure if I am doing it right, what is mistake in my code and should I put this logic in onClick or in onChange method?

CodePudding user response:

I don't know if this will help you but here are the some problems I see here


array.map((j) => j) is same as array just maps the array to itself


let array = [];
newComment.split(" ").map((word) => {
    array.push(word.split("#")[1]);
});

map is a transformation function but used here to make a loop
If you want to use map properly then do this

let array = newComment.split(" ").map(word => word.split("#")[1]);

i.display.includes(array.map((j) => j))
display is a string and array is an array
You are checking if a string includes an array which doesn't make any sense
I assume what you are trying to do is

hashtagData.some(i => array.includes(i.display))

CodePudding user response:

Assuming .split(" ") is sufficient for "words" for your purposes, then what you have isn't too far off. Some notes:

  • It's misleading to use map if you aren't using the array it creates (more in my blog post about it).
  • word.split("#")[1] will give you undefined for words that don't have # in them, which you probably want to weed out.
  • i.display.includes(array.map((j) => j)) doesn't work for a couple of reasons:
    • array.map((j) => j) is pointless, it just creates a copy of the array.
    • includes expects a string as its argument, not an array, so will convert the array to a string; that joins together the array entries with commas in-between, which won't match your hashtags.

Instead, something along these lines:

const newTags =
    // Split the comment into "words"
    newComment.split(" ")
    // Get the "words" that are hashtags (or `undefined` for ones that aren't)
    .map(word => word.split("#")[1])
    // Filter out the "words" that either A) Are `undefined` or B) Are already known
    // in `hashtagData`
    .filter(word => word !== undefined && !hashtagData.some(tag => tag.display === word));

That gives you an array of the new hashtags in the comment (empty if none).

Live Example:

Show code snippet

const hashtagData = [
    { id: 0, display: "end" },
    { id: 1, display: "start" },
];
const newComment = "sample text for already present hashtag #end and manually entered #newHashtag";
const newTags =
    // Split the comment into "words"
    newComment.split(" ")
    // Get the "words" that are hashtags (or `undefined` for ones that aren't)
    .map(word => word.split("#")[1])
    // Filter out the "words" that either A) Are `undefined` or B) Are already known
    // in `hashtagData`
    .filter(word => word !== undefined && !hashtagData.some(tag => tag.display === word));
console.log(newTags);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

If you just need a flag instead, use some instead of filter at the end:

const hasNewTag =
    // Split the comment into "words"
    newComment.split(" ")
    // Get the "words" that are hashtags (or `undefined` for ones that aren't)
    .map(word => word.split("#")[1])
    // See if there's any "word" that is both A) Not `undefined`, and B) Not already
    // known in `hashtagData`
    .some(word => word !== undefined && !hashtagData.some(tag => tag.display === word));

Live Example:

Show code snippet

const hashtagData = [
    { id: 0, display: "end" },
    { id: 1, display: "start" },
];
const newComment = "sample text for already present hashtag #end and manually entered #newHashtag";
const hasNewTag =
    // Split the comment into "words"
    newComment.split(" ")
    // Get the "words" that are hashtags (or `undefined` for ones that aren't)
    .map(word => word.split("#")[1])
    // See if there's any "word" that is both A) Not `undefined`, and B) Not already
    // known in `hashtagData`
    .some(word => word !== undefined && !hashtagData.some(tag => tag.display === word));
console.log(hasNewTag);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You should use Regex

Pattern

([^a-z] [a-z]*)*

Select groups

  • Related