How can I remove text(e.g ["88664734","88639280","88676217"]) from a strReviewers string which contains list of Reviewers separated by semicolon and then join the whole string again either using JavaScript or jQuery?
I get a dynamic string(strReviewers) which contains multiple user records separated by comma:
I need to remove whole user record if I pass an array of ids. e.g ["88664734","88639280","88676217"]
var strReviewers = "88664734*,*Andrew Farmer*,*19042*,**,*,19013,19017,19042,19043,19051,*;*88639280*,*Sally Hopewell*,*19042*,**,*,19013,19017,19042,19043,*;*88686221*,*Jonathan Rees*,*19042*,**,*,19013,19017,19042,19043,19060,*;*88676217*,*James Wason*,*19042*,**,*,19013,19017,19042,19043,*;*";
strReviewers contains user records separated by semicolon and each user record is separated by ,.
Each record contains 1 user which is in the shape of userid then following by name then following by roleid then following by txtSpeciality following by then rolelist.
/*
88664734*,*Andrew Farmer*,*19042*,**,*,19013,19017,19042,19043,19051,*;
*88639280*,*Sally Hopewell*,*19042*,**,*,19013,19017,19042,19043,*;
*88686221*,*Jonathan Rees*,*19042*,**,*,19013,19017,19042,19043,19060,*;
*88676217*,*James Wason*,*19042*,**,*,19013,19017,19042,19043,*;
*/
I have done it using the following code but wondering this can be achieved some other easier way?
var strReviewers = "88664734*,*Andrew Farmer*,*19042*,**,*,19013,19017,19042,19043,19051,*;*88639280*,*Sally Hopewell*,*19042*,**,*,19013,19017,19042,19043,*;*88686221*,*Jonathan Rees*,*19042*,**,*,19013,19017,19042,19043,19060,*;*88676217*,*James Wason*,*19042*,**,*,19013,19017,19042,19043,*;*";
function removeReviewerByID(ids = []) {
return strReviewers
.split(";")
.map(item => item.split("*,*"))
.filter(item => item[0] !== "*")
.map(item => ({
userid:item[0],
name:item[1],
roleid:item[2],
txtSpeciality:item[3],
rolelist:item[4]
}))
.filter(item => (!ids.includes(item["userid"]) && !ids.includes(item["userid"].replace(/\*/g, ''))))
.map(item => ({
record: item["userid"].concat("*,*").concat(item["name"]).concat("*,*").concat(item["roleid"]).concat("*,*").concat(item["txtSpeciality"]).concat("*,*").concat(item["rolelist"]).concat(";")
}))
.reduce((accumulator, item) => {
return accumulator.concat(item["record"]);
}, "")
}
console.log(removeReviewerByID(["88664734","88639280","88676217"]));
CodePudding user response:
One approach would be to use a regular expression. Turn the array of IDs into a pattern by joining by |
, and then filter for records that don't start with the pattern.
To keep the data structure consistent, consider using .match(/.*?\*;\*/g)
instead of .split(";")
- by matching, you'll be preserving the formatting (where the first item doesn't start with a *
, and where the final item is terminated by ,*;*
)
var strReviewers = "88664734*,*Andrew Farmer*,*19042*,**,*,19013,19017,19042,19043,19051,*;*88639280*,*Sally Hopewell*,*19042*,**,*,19013,19017,19042,19043,*;*88686221*,*Jonathan Rees*,*19042*,**,*,19013,19017,19042,19043,19060,*;*88676217*,*James Wason*,*19042*,**,*,19013,19017,19042,19043,*;*";
function removeReviewerByID(ids = []) {
const pattern = new RegExp(`^(?:${ids.join('|')})\\*`);
return strReviewers
.match(/.*?\*;\*/g)
.filter(str => !pattern.test(str))
.join('');
}
console.log(removeReviewerByID(["88664734", "88639280", "88676217"]));
It would be possible to do it in a single regular expression replacement, though it'd be more confusing.
var strReviewers = "88664734*,*Andrew Farmer*,*19042*,**,*,19013,19017,19042,19043,19051,*;*88639280*,*Sally Hopewell*,*19042*,**,*,19013,19017,19042,19043,*;*88686221*,*Jonathan Rees*,*19042*,**,*,19013,19017,19042,19043,19060,*;*88676217*,*James Wason*,*19042*,**,*,19013,19017,19042,19043,*;*";
function removeReviewerByID(ids = []) {
const pattern = new RegExp(
String.raw`(?:^|(?<=\*;\*))(?:${ids.join('|')})\*.*?\*;\*`,
'g'
);
return strReviewers.replace(pattern, '');
}
console.log(removeReviewerByID(["88664734", "88639280", "88676217"]));
/(?:^|(?<=\*;\*))(?:88664734|88639280|88676217)\*.*?\*;\*/g
means:
(?:^|(?<=\*;\*))
- Match either^
- Start of line, or(?<=\*;\*)
- A position preceded by*;*
(the start of a reviewer section)
(?:88664734|88639280|88676217)
- Match any of the IDs\*
- Match a literal*
(make sure the ID ends here).*?
- Match any characters, lazily, until encountering\*;\*
- The characters*;*
This approach matches and removes the delimiter between reviewers at the end of each match.
CodePudding user response:
Another approach
var strReviewers = "88664734*,*Andrew Farmer*,*19042*,**,*,19013,19017,19042,19043,19051,*;*88639280*,*Sally Hopewell*,*19042*,**,*,19013,19017,19042,19043,*;*88686221*,*Jonathan Rees*,*19042*,**,*,19013,19017,19042,19043,19060,*;*88676217*,*James Wason*,*19042*,**,*,19013,19017,19042,19043,*;*";
var excluded = ["88664734","88639280","88676217"];
var result = strReviewers
.split(';')
.reduce((acc, curr) => {
let userid = curr.split('*,*')[0].replace(/\*/, ''); //remove * from userid
if(!excluded.includes(userid)) {
acc.push(curr);
}
return acc;
}, [])
.join(';');
console.log(result);
CodePudding user response:
Here is a short and sweet answer using a .split()
, .filter()
, and .join()
:
var strReviewers = "88664734*,*Andrew Farmer*,*19042*,**,*,19013,19017,19042,19043,19051,*;*88639280*,*Sally Hopewell*,*19042*,**,*,19013,19017,19042,19043,*;*88686221*,*Jonathan Rees*,*19042*,**,*,19013,19017,19042,19043,19060,*;*88676217*,*James Wason*,*19042*,**,*,19013,19017,19042,19043,*;*";
var excluded = ["88664734","88639280","88676217"];
var excludedRegex = new RegExp('\\*?(' excluded.join('|') ')\\b');
//var excludedRegex = new RegExp(excluded.join('|'));
var result = strReviewers
.split(';')
.filter(item => !item.match(excludedRegex))
.join(';');
console.log(result);
Output:
*88686221*,*Jonathan Rees*,*19042*,**,*,19013,19017,19042,19043,19060,*;*
Explanation:
- the
excludedRegex
is the regex representation of theexcluded
array - the filter returns false on a regex match, e.g. an exclude