问题
I have a scenario in nodeJS.
I have an object which contains number of elements and array
var Obj = {
count: 3,
items: [{
"organizationCode": "FP1",
"organizationName": "FTE Process Org"
},
{
"organizationCode": "T11",
"organizationName": "FTE Discrete Org"
},
{
"organizationCode": "M1",
"organizationName": "Seattle Manufacturing"
}
]
};
The scenario is like this. I have to filter result based on criteria.
I have print output if either organizationCode
or organizationName
starts with
particular character or ends with
or it contains
particular word.
for eg if user enters starts with M
or starts with "M"
below should return
{
"organizationCode": "M1",
"organizationName": "Seattle Manufacturing"
}
if user enters ends with org then
{
"organizationCode": "FP1",
"organizationName": "FTE Process Org"
}, {
"organizationCode": "T11",
"organizationName": "FTE Discrete Org"
},
and if it enters contains 11
then below should return.
{
"organizationCode": "T11",
"organizationName": "FTE Discrete Org"
},
I have thousands of record. I am looking for optimize way to get output. I am new to NodeJs
so struggling to complete it.
回答1:
First thing first. here some string functions that u can use:
endsWith
"some string".endsWith('string')
startsWith
"some string".startsWith('some')
includes
"some string".includes('ome')
And you can convers object with Object.values().
But if i was doing this, i would probably tho something like following,
// I'm assuming in the nodejs you would have some variables to search for
// like whereToSearch and whatToSearch lets say
var arrToSearch = [
{ organizationCode: "FP1", organizationName: "FTE Process Org" },
{ organizationCode: "T11", organizationName: "FTE Discrete Org" },
{ organizationCode: "M1", organizationName: "Seattle Manufacturing" },
];
function search(arr, whereToSearch, whatToSearch) {
return arr.filter(
(ch) =>
ch.organizationCode[whereToSearch](whatToSearch) ||
ch.organizationName[whereToSearch](whatToSearch)
);
}
console.log(search(arrToSearch, "endsWith", "11"));
// We can also send the array to function so in this case your object is here
var object = {
count: 3,
items: [
{
organizationCode: "FP1",
organizationName: "FTE Process Org",
},
{
organizationCode: "T11",
organizationName: "FTE Discrete Org",
},
{
organizationCode: "M1",
organizationName: "Seattle Manufacturing",
},
],
};
//and what you can do with this is
console.log(search(object.items, "startsWith", "FTE"));
回答2:
You can use Array.filter in conjunction with String.startsWith, String.includes and String.endsWith.
回答3:
You can use an array filter, to go trough all of the elements and process them as you need.
Also to check if a string contains another string you can use an insensitive match on it.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
var Obj = {
count: 3,
items: [
{
organizationCode: "FP1",
organizationName: "FTE Process Org",
},
{
organizationCode: "T11",
organizationName: "FTE Discrete Org",
},
{
organizationCode: "M1",
organizationName: "Seattle Manufacturing",
},
],
};
const filter = (starts_with, ends_with, contains) => {
const result = Obj.items.filter(item => {
if(starts_with){
return (
item.organizationCode[0].toLowerCase() === starts_with.toLowerCase() ||
item.organizationName[0].toLowerCase() === starts_with.toLowerCase()
) ? true : false
} else
if(ends_with) {
return (
item.organizationCode[item.organizationCode.length].toLowerCase() === ends_with.toLowerCase() ||
item.organizationName[item.organizationName.length].toLowerCase() === ends_with.toLowerCase()
) ? true : false
} else {
return (
item.organizationCode.match(contains,'i') ||
item.organizationName.match(contains,'i')
) ? true : false
}
});
return result;
};
console.log(filter("F",null,null)); // test run
回答4:
Here is a simple solution analyzing initially the user condition and the filtering your list.
It has several improvement points but it is a good start.
const analyzeCond = condition => {
let conditionParts = condition.split(' ').filter(str => str !== '');
if (conditionParts.length < 3) {
return null;
}
// Check field
const fieldName = conditionParts.shift();
if (!['organizationCode', 'organizationName'].includes(fieldName)) {
return null;
}
// Check operator
const operator = conditionParts.shift();
if (['starts', 'ends'].includes(operator)) {
const withWord = conditionParts.shift();
if (withWord !== 'with') {
return null;
}
} else if (operator !== 'contains'){
return null;
}
const userText = conditionParts.join(' ');
return { fieldName, operator, userText };
};
const compareFns = {
starts: (query, text) => text.startsWith(query),
ends: (query, text) => text.endsWith(query),
contains: (query, text) => text.includes(query),
};
const filter = (list, userInput) => {
const condition = analyzeCond(userInput);
if (condition === null) {
return null;
}
// Filter based on user input
return list.filter(item => {
return compareFns[condition.operator](condition.userText, item[condition.fieldName]);
});
};
const obj = {
count: 3,
items: [{
"organizationCode": "FP1",
"organizationName": "FTE Process Org"
},
{
"organizationCode": "T11",
"organizationName": "FTE Discrete Org"
},
{
"organizationCode": "M1",
"organizationName": "Seattle Manufacturing"
}]
};
// Example execution with ugly but possible user input
const result = filter(obj.items, ' organizationName starts with Seattle Ma');
if (result !== null) {
console.log('Filter result', result);
} else {
console.log('The user input has not the expected format');
}
Things to check:
Check if you want to support multiple continued space characters or not (you can adapt this code if needed).
You could easily add more operators or fields to compare against.
If the user conditions you want to support in the future are more complex I'd recommend to use a parser package to not reinvent the well.
If you are in big project and want to implement complex searches, consider using services like ElasticSearch.
来源:https://stackoverflow.com/questions/61924759/string-operation-in-nodejs-objects