Filtering Data By Full Name React - javascript

Hi I am Trying to filter my Data By Full Name, my API takes in a first and last name and I am returning it as:
const filteredStudents = students.filter( student => {
return (student.firstName.toLowerCase().includes(search.toLowerCase()) + student.lastName.toLowerCase().includes(search.toLowerCase()));
})
which only shows a result when typing a first or last name is there a way to handle a condition for when you type in the whole name?
For Example, "Bill Gates"

You can concatenate the names first, then check if the search term is contained.
const filteredStudents = students.filter((student) => {
return `${student.firstName} ${student.lastName}`
.toLowerCase()
.includes(search.toLowerCase());
});

Related

Applying a regex to the result of a fetch function that is placed inside a useState?

I have a fetch function that produces a numbered list of uses (ie. 1. To Drive, 2. To Speed, ...)
The function returns a string of text, which I am then applying a regex on to convert it into an array, where each value in the array is one of the points in the list.
I am using this regex, I know it works.
let input = '1. Hello. 2. Bye.'
llet regex = /(\d+\.\d*)\s?(.*?)(?=\d+\.|$)/gs;
let matches = input.match(regex);
It returns an array ['1. Hello', '2. Bye'].
I have tried to apply the regex to the response value within the fetch function. When I used console.log it was blank, so it seems like nothing has changed.
const [inputMatches, setInputMatches] = useState([]);
const getUses = async () => {
openai.createCompletion({
model: "text-davinci-003",
prompt: "List four uses for a car",
max_tokens: 256
}).then((response) => {
let regex = /(\d+\.\d*)\s?(.*?)(?=\d+\.|$)/gs
setInputMatches((response.data.choices[0].text).match(regex))
})
};
The getUses starts when I click a button which is linked to another function within useEffect, I could share it if required but it seems unrelated.

How to remove number ( item ) from array and show only strings? using vanilla js

i got results:
link https://api/v1/3
link https://api/v1/3/user
link https://api/v1/3/customer
link https://api/v1/3/suppliers
i am filtering this results and show only
3, user, customer, suppliers
but i want to show only
user, customer, suppliers
I want to remove 3... in loop this 3 in seconds interation will be 2 or any other number..
My try
const result = obj.links.map((o) => o.href.split("/").pop());
and
const result = obj.links.map((o) => o.href.replace(/.*(?=\/)/, "").slice(1));
but in both case i print 3 ...
i want to show only :
user, customer, suppliers
You can use Array.prototype.reduce along with a check if the element popped loosely equals itself cast to a Number.
const links = [{"href": "https://api/v1/3"},{"href": "https://api/v1/3/user"},{"href": "https://api/v1/3/customer"},{ "href": "https://api/v1/3/suppliers"}];
const result = links.reduce((acc, {href: link}) => {
const last = link.split('/').pop();
if (!(last == Number(last))) acc.push(last);
return acc;
}, []);
console.log(result);
You could achieve the same with a map followed by a filter, but that would have to iterate your array twice.

Split string using elements of array JavaScript

Hello i'm working on dynamic search for my first web application
and i have a huge problem i've been working on this for several hours using diffrent solutions in the end i think this might be the closest to resolving my problems.
Search is not static so hard coding this is not an option.
const search = 'someone loves some thing';
const teams = ['some thing', 'someone', 'help'];
const twoTeams = [];
if (teams.some(el => search.includes(el))) {
teams.forEach(word => {
if (search.includes(word)) {
twoTeams.push(word);
}
})
}
console.log(twoTeams); // ['some thing','someone']
console.log(search) // 'someone loves some thing'
// looking for // console.log(twoTeams)// 'someone','some thing'
And here im stuck i have array of items that i need to split string with to access data from API i just need it in that order i cant reverse order because in the app theres too many elements in array and user can search anything so you dont know which one should will be index[0] and which one should be index[1] and thats crucial to my dynamic search.
First of all, I'd start with removing the outer if as we check every word anyway in the inner condition.
teams.forEach(word => {
// Get the position of word in the search text. Negative value means that there is no match.
let index = search.indexOf(word);
// If the search text contains the word
if (index >= 0) {
// Save both the matching word and its index
twoTeams.push( { 'word': word, 'index': index});
}
})
// Sort the results by the index and select the word only
twoTeams = results.sort((a,b)=> a.index - b.index).map(result => result.word);
You can simplify your code to built twoTeams object with filter like below.
const twoTeams = teams.filter(el => search.includes(el));
As you want preserve order then you can sort your results with indexOf like below.
twoTeams.sort((a, b) => search.indexOf(a) - search.indexOf(b));
Try it below.
const search = 'someone loves some thing';
const teams = ['some thing', 'someone', 'help'];
const twoTeams = teams.filter(el => search.includes(el));
twoTeams.sort((a, b) => search.indexOf(a) - search.indexOf(b));
console.log(twoTeams); // looking for ['someone', 'some thing']
console.log(search) // 'someone loves some thing'

Trouble with React/JS filter

I am trying to implement a filter function that is able to search in two separate JSON fields when a user types in a search bar. Searching the whole JSON returns errors and if I repeat this function, the two similar functions cancel each other out.
My current filter function:
let filteredOArt = origArt.filter((origAItem) => {
return origAItem.authors.toLowerCase().includes(this.state.search.toLowerCase())
});
I want to be able to have the search look within the "authors" field as well as a "description" field.
Before the React render, I have this function listening to the state:
updateSearch(event) {
this.setState({ search: event.target.value })
}
Then my search function is in an input field in the React return:
<h6>Search by author name: <input type="text" value={this.state.search} onChange={this.updateSearch.bind(this)} /></h6>
You can tweak the function a bit like this
let filteredOArt = origArt.filter((origAItem) => {
return (
(origAItem.authors.toLowerCase().includes(this.state.search.toLowerCase())||
(origAItem.description.toLowerCase().includes(this.state.search.toLowerCase())
)
)
});
You actually can do a filter for both fields.
Given you have your searchValue and your array with the objects you could filter this way:
const filterByAuthorOrDescription = (searchValue, array) =>
array.filter(
item =>
item.authors.toLowerCase().includes(searchValue.toLowerCase()) ||
item.description.toLowerCase().includes(searchValue.toLowerCase())
);
const filtered = filterByAuthorOrDescription(this.state.search, articles);
filtered will now contain an array of objects that contain your searchValue in either description or authors that you can map through.
You could use some to check if the filter is positive for at least one field :
let filteredOArt = origArt.filter(origAItem => ['authors', 'description'].some(field => origAItem.[field].toLowerCase().includes(this.state.search.toLowerCase())))
Just iterate over the different field names you want to use.
Some will return true if any of the fields mentioned contains your string and avoid repetitions in your code.
Long syntax :
origArt.filter(origAItem => {
return ['authors', 'description'].some(field => origAItem.[field].toLowerCase().includes(this.state.search.toLowerCase()))
})

How to filter data with an array of strings matching at least one?

I'm quite new to ReactJS and work on a simple application which shows many different data (called apps). I want to implement a live free text search-filter. For that I'm using an Input Element, calling a JavaScript function if the value is changing. It's working quite good. But only for one string. If I want to filter for more words it's handled as an "AND" filter. But I want an "OR" filter.
I have the apps and filter them with a searchString. The User has to input at least three characters. If the user enters two words with three characters f.e. 'app' and 'red', I want to filter for the elements which has the words 'app' OR 'red' in the title. If min. one of the filter-strings matches, the app is shown. That's the plan.
I tried with .indexOf(), .includes() and nothing matches, even in the documentation I found nothing like an "OR" filter-search.
Here is my code, working for one string:
updateSearch(event) {
let searchString = event.target.value.toLowerCase()
let searchStringSplit = searchString.split(/(\s+)/).filter( function(e) { return e.trim().length >=3; } ); //Only words with at least 3 chars are allowed in the array
if (searchString.length >= 3) { //Check if the minimun amount of characters is fullfilled
let allApps = this.props.applications;
let apps = allApps.filter(app =>
app.title.toLowerCase().includes(searchString)
);
this.props.updateApplications(apps);
} else {
this.clearSearch()
}
}
my Input element:
<Input
id="freeTextSearch"
className="searchInput"
onChange={this.updateSearch.bind(this)}
autoComplete="off"
action={
<Button
id="freeTextSearchButton"
name="search"
icon="search"
onClick={() => this.clearSearch()}
/>
}
placeholder="Search"
/>
Thanks for the help
Yvonne
ANSWER:
Thank you 'Silvio Biasiol'. Your Solution gave me the right hint. Now I have an 'OR' filter-search matching at least one word. The function now looks like:
updateSearch(event) {
let searchString = event.target.value.toLowerCase()
let searchStringSplit = searchString.split(/(\s+)/).filter( function(e) { return e.trim().length >=3; } )
if (searchStringSplit.length >=1) { //Check if there is at least on word with tree letters
let allApps = this.props.applications
// If at least a word is matched return it!
let apps = allApps.filter(app => {
let containsAtLeastOneWord = false
searchStringSplit.forEach(searchWord => {
if (app.title.toLowerCase().includes(searchWord))
containsAtLeastOneWord = true;
})
if (containsAtLeastOneWord)
return app
}
);
this.props.updateApplications(apps)
} else { // user deletes manually every word
this.clearSearch()
}
}
Thanks at everyone
If you just want to match at least one word than it's pretty easy :)
let string = "My cool string"
let possibleStrings = [
'My cool string',
'My super cool string',
'Another',
'I am lon but sadly empty',
'Bruce Willis is better than Pokemon',
'Another but with the word string in it',
'Such string much wow cool']
// Split spaces
let searchString = string.toLowerCase().split(' ')
// Log the result, just wrap it in your react script
console.log(possibleStrings.filter(string => {
let containsAtLeastOneWord = false;
// If at least a word is matched return it!
searchString.forEach(word => {
if (string.toLowerCase().includes(word))
containsAtLeastOneWord = true;
})
if (containsAtLeastOneWord)
return string
}))
You are not using your searchStringSplit array. Using this array you could do the following:
const searchRegex = new RegExp(searchStringSplit.join("|"))
let apps = allApps.filter(app =>
searchRegex.test(app.title.toLowerCase())
);
You join your searchStringSplit array into a regex with the form term1|term2|term3... and match it aginst the title.
Another option would be to use the Array.prototype.some() function like this:
let apps = allApps.filter(app =>
searchStringSplit.some(searchString => app.title.toLowerCase().includes(searchString))
);
You fitler all your apps and for each app you check if it's title includes 'some' of the search strings.
trying to understand your code, suppose that searchString is "facebook twitter youtube"
let searchStringSplit = searchString.split(/(\s+)/).filter( function(e) { return e.trim().length >=3; } );
//searchStringSplit is like [ "facebook", "twitter", "youtube" ]
//allApps is like ["TWITTER","INSTAGRAM"]
allApps.filter(app=> searchStringSplit.includes(app.toLowerCase()))
//returning me all apps in allApps that are includes in searchStringSplit
// so return ["TWITTER"]
not sure if it's exactly what you need...if it's not please let me know so I can change the answer...

Categories

Resources