I have a const teams
. I want to split this array
into two array
. The first team should be the team without a number in the first character of the name, and the second team should be with numbers in the first character of the team.
const [teams, setTeam] = useState([]);
const teams = [{id: 1, name: "1-First"},
{id: 2, name: "Winner"},
{id: 3, name: "2-Second"}]
// teamsWithNumber
var myArray = teams.filter(function (obj) {
return obj.name.match('/^[A-Z0-9]/i')
});
const teamsWithNumber = myArray;
// teamsWithOUTNumber
var myArray = teams.filter(function (obj) {
return obj.name!== obj.name.match('/^[A-Z0-9]/i')
});
const teamsWithOUTNumber = myArray;
My output is
// console.log(teamsWithOUTNumber)
[OUT] []
My desired output
teamsWithOUTNumber = [id: 2, name: "Winner"}]
teamsWithNumber = [{id: 1, name: "1-First"},
{id: 3, "2-Second"}]
CodePudding user response:
Your understanding of RegExp seems to have a few fundamental flaws - you may find it helpful to use a utility like Regex101 to assist with a more plain-English explanation of what your pattern does. For the one you've provided above, the tool specifically states:
^
asserts position at start of a line- Match a single character present in the list below
[A-Z0-9]
A-Z
matches a single character in the range betweenA
(index65
) andZ
(index90
) (case sensitive)0-9
matches a single character in the range between0
(index48
) and9
(index57
) (case sensitive)
Since you've opted to wrap the RegExp literal in quotes, you've also inadvertently included the /
characters as well, which none of the data you're testing against contains. As such, both patterns of data in obj.name
will never match this pattern each time (with and without the leading digit-hyphen combination), leading to the results you're seeing.
Instead, tailor the pattern to express exactly what you're expecting to filter into each array. I've provided /^\d-/
below, which explicitly matches strings beginning with a leading digit followed by a hyphen. This should more closely match what you seem to be going for.
Somewhat tangentially, since you're not trying to extract any data in this scenario, you should also opt for RegExp.test()
over String.match()
.
Finally, you can make your code meet your reuqirements and a bit more succinct by running filter
on the same original array and storing the result into two separate variables - one operation to filter those that do conform to the pattern ^\d-
(teamsWithNumber
), and those that do not (teamsWithOUTNumber
):
const teams = [{
id: 1,
name: "1-First"
},
{
id: 2,
name: "Winner"
},
{
id: 3,
name: "2-Second"
}
]
const teamsWithNumber = teams.filter(obj => /^\d-/.test(obj.name));
const teamsWithOUTNumber = teams.filter(obj => /^(?!\d-)/.test(obj.name));
console.log(teamsWithNumber, teamsWithOUTNumber);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Can you try this? I changed filters returned values.
const [teams, setTeam] = useState([]);
const teams = [{id: 1, name: "1-First"},
{id: 2, name: "Winner"},
{id: 3, name: "2-Second"}]
// teamsWithNumber
var myArray = teams.filter(function (obj) {
return !/^[-]?\d $/.test(obj.name[0]);
});
const teamsWithNumber = myArray;
// teamsWithOUTNumber
var myArray = teams.filter(function (obj) {
return !/^[-]?\d $/.test(obj.name[0]);
});
const teamsWithOUTNumber = myArray;
CodePudding user response:
.match('/^[A-Z0-9]/i')
will not work, the RegExp
literal is a string: use .match(/^[A-Z0-9]/i)
.
Actually, you only need to test for /^\d/
(the first character of the string to test is a number). Check RegExp @ MDN.
You can use a reducer using that test, something like
const teams = [{
id: 1,
name: "1-First"
},
{
id: 2,
name: "Winner"
},
{
id: 3,
name: "2-Second"
}
];
const [numbered, notNumbered] = teams
.reduce(([t1, t2], val) =>
[...[t1, t2], /^\d/.test(val.name) ? t1.push(val) : t2.push(val)], [ [], [] ]);
console.log(`with number: ${
JSON.stringify(numbered)}, \nno number: ${
JSON.stringify(notNumbered)}`);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>