Home > database >  Split an array in two differents objects
Split an array in two differents objects

Time:10-21

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 between A (index 65) and Z (index 90) (case sensitive)
    • 0-9 matches a single character in the range between 0 (index 48) and 9 (index 57) (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>

  • Related