I’m trying to build a searchable menu of teams in Javascript/TypeScript – not sure how to do it.
Basically, I have a set of data laid out like this.
const data = [
{
'name': 'Alex A',
'agentId': '1225',
},
{
'name': 'Tammy',
'agentId': '125',
'team': [
{
'name': 'Alex B',
'agentId': 249
},
{
'name': 'Alexander C',
'agentId': 148
},
{
'name': 'Ed',
'agentId': 382
}
]
},
{
'name': 'Edward',
'agentId': '594',
'team': [
{
'name': 'Daniel',
'agentId': 152
},
{
'name': 'Alexis D',
'agentId': 1900
}
]
}
];
When I search (i.e. Alex) so my new data set would be:
const data = [
{
'name': 'Alex A',
'agentId': '1225',
},
{
'name': 'Tammy',
'agentId': '125',
'team': [
{
'name': 'Alex B',
'agentId': 249
},
{
'name': 'Alexander C',
'agentId': 148
}
]
},
{
'name': 'Edward',
'agentId': '594',
'team': [
{
'name': 'Alexis D',
'agentId': 1900
}
]
}
];
I am more familiar with PHP so I would do something along the lines of:
$x = 0;
foreach($data as $row){
if (strpos($row.name, 'alex')) {
$newArray[$x] = $row;
}
foreach($row['team'] as $person) {
if (strpos($person.name, 'alex')) {
if(!isset($newArray[$x])) {
$newArray[$x] = $row;
}
$newArray[$x]['team'][] = $person;
}
$x++;
}
}
Been working with Typescript within the last few months, so this is the rabbit hole i’m going down, but I know it’s not right.
const searchName = "Alex";
const newArray = [];
if (searchName.length >= 3) {
const filtered = data.forEach((user) => {
const name = user.name.toLowerCase();
if (name.indexOf(searchName.toLowerCase())) {
newArray.push(user);
}
if (user.team) {
const teamFiltered = user.team.forEach((member) => {
if (member.name.indexOf(searchName.toLowerCase())) {
newArray.push({
name: user.name,
agentId: user.agentId,
team: member,
});
}
});
}
});
}
3
Answers
First iterate over each array item and create a new
team
property (if it exists in the first place) with onlyAlex
es in it.Then apply another filter so that the top-level items only contain those with names that match, or whose
team
property is not empty.Here is the function
And call it this way passing it the array you want to filter and the lookup value:
We can start by defining the type for your
data
. We will make sure our solution works for data nested to any depth –Next we write
filter
as a mutually recursive function. This technique is excellent for processing tree-like data. We have two functions –many
that processes a list of elementsone
that processes a single elementUsing the tandem pair we can easily filter the data with minimal complexity –
Run the demo below to verify the result in your own browser or on typescript playground –
An obvious improvement would be to make
filter
a higher-order funciton, much likeArray.prototype.filter
. Instead of a fixedquery: string
parameter, we can use afunc: (agent: Agent) => boolean)
parameter, allowing the caller tofilter
with much greater flexibility –The caller can specify exactly how the data is filtered now. This will produce the same result as before –
But maybe the caller wishes to filter using regex –
Or perhaps you want to filter by
agentId
–You can verify these examples on typescript playground.