Is there a better way to extract information from a string?












12














Let's say I have an array of strings, and I need specific info from them, what would be an easy way to do that?



Suppose the array was this



let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];


Let's say I wanted the date extracted and saved into another array, well I could make a function like this



function extractDates(arr){
let dateRegex = /(d{1,2}/){2}d{4}/g, dates = "";
let dateArr = ;
for(let i = 0; i<arr.length; i++){
dates = /(d{1,2}/){2}d{4}/g.exec(arr[i])
dates.pop();
dateArr.push(dates);
}
return dateArr.flat();
}


Although this works, it is clunky and requires I pop() because it will return an array of arrays, ie: ["12/16/1988", "16/"], plus I need to call flat afterwards.



Another option would be to substring the strings, with a given position, where I need to know a regex pattern.



function extractDates2(arr){
let dates = ;
for(let i = 0; i<arr.length; i++){
let begin = regexIndexOf(arr[i], /(d{1,2}/){2}d{4}/g);
let end = regexIndexOf(arr[i], /[0-9] /g, begin) + 1;
dates.push(arr[i].substring(begin, end));
}
return dates;
}


And of course have a regexIndexOf function



function regexIndexOf(str, regex, start = 0){
let indexOf = str.substring(start).search(regex);
indexOf = (indexOf >= 0) ? (indexOf + start) : -1;
return indexOf;
}


Again this function also works, but it seems like an awful lot just to extract something simple. Is there an easier way to extract data into an array?










share|improve this question


















  • 3




    Why not use array.map?
    – Henry Howeson
    2 days ago










  • @HenryHoweson .map (alone) won't work if there's more than one date in one of the input strings, eg "1 Ben Howard 12/16/1988 apple 1/10/1999 ", he'd have to flatten it afterwards
    – CertainPerformance
    2 days ago








  • 1




    @CertainPerformance With the regex global flag set it would work fine, also the OP doesn't appear to require that.
    – Henry Howeson
    2 days ago










  • @HenryHoweson Just using the global flag doesn't allow for (concise) extraction of matches from multiple strings into a single array, I thought? What code are you thinking of?
    – CertainPerformance
    2 days ago


















12














Let's say I have an array of strings, and I need specific info from them, what would be an easy way to do that?



Suppose the array was this



let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];


Let's say I wanted the date extracted and saved into another array, well I could make a function like this



function extractDates(arr){
let dateRegex = /(d{1,2}/){2}d{4}/g, dates = "";
let dateArr = ;
for(let i = 0; i<arr.length; i++){
dates = /(d{1,2}/){2}d{4}/g.exec(arr[i])
dates.pop();
dateArr.push(dates);
}
return dateArr.flat();
}


Although this works, it is clunky and requires I pop() because it will return an array of arrays, ie: ["12/16/1988", "16/"], plus I need to call flat afterwards.



Another option would be to substring the strings, with a given position, where I need to know a regex pattern.



function extractDates2(arr){
let dates = ;
for(let i = 0; i<arr.length; i++){
let begin = regexIndexOf(arr[i], /(d{1,2}/){2}d{4}/g);
let end = regexIndexOf(arr[i], /[0-9] /g, begin) + 1;
dates.push(arr[i].substring(begin, end));
}
return dates;
}


And of course have a regexIndexOf function



function regexIndexOf(str, regex, start = 0){
let indexOf = str.substring(start).search(regex);
indexOf = (indexOf >= 0) ? (indexOf + start) : -1;
return indexOf;
}


Again this function also works, but it seems like an awful lot just to extract something simple. Is there an easier way to extract data into an array?










share|improve this question


















  • 3




    Why not use array.map?
    – Henry Howeson
    2 days ago










  • @HenryHoweson .map (alone) won't work if there's more than one date in one of the input strings, eg "1 Ben Howard 12/16/1988 apple 1/10/1999 ", he'd have to flatten it afterwards
    – CertainPerformance
    2 days ago








  • 1




    @CertainPerformance With the regex global flag set it would work fine, also the OP doesn't appear to require that.
    – Henry Howeson
    2 days ago










  • @HenryHoweson Just using the global flag doesn't allow for (concise) extraction of matches from multiple strings into a single array, I thought? What code are you thinking of?
    – CertainPerformance
    2 days ago
















12












12








12


4





Let's say I have an array of strings, and I need specific info from them, what would be an easy way to do that?



Suppose the array was this



let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];


Let's say I wanted the date extracted and saved into another array, well I could make a function like this



function extractDates(arr){
let dateRegex = /(d{1,2}/){2}d{4}/g, dates = "";
let dateArr = ;
for(let i = 0; i<arr.length; i++){
dates = /(d{1,2}/){2}d{4}/g.exec(arr[i])
dates.pop();
dateArr.push(dates);
}
return dateArr.flat();
}


Although this works, it is clunky and requires I pop() because it will return an array of arrays, ie: ["12/16/1988", "16/"], plus I need to call flat afterwards.



Another option would be to substring the strings, with a given position, where I need to know a regex pattern.



function extractDates2(arr){
let dates = ;
for(let i = 0; i<arr.length; i++){
let begin = regexIndexOf(arr[i], /(d{1,2}/){2}d{4}/g);
let end = regexIndexOf(arr[i], /[0-9] /g, begin) + 1;
dates.push(arr[i].substring(begin, end));
}
return dates;
}


And of course have a regexIndexOf function



function regexIndexOf(str, regex, start = 0){
let indexOf = str.substring(start).search(regex);
indexOf = (indexOf >= 0) ? (indexOf + start) : -1;
return indexOf;
}


Again this function also works, but it seems like an awful lot just to extract something simple. Is there an easier way to extract data into an array?










share|improve this question













Let's say I have an array of strings, and I need specific info from them, what would be an easy way to do that?



Suppose the array was this



let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];


Let's say I wanted the date extracted and saved into another array, well I could make a function like this



function extractDates(arr){
let dateRegex = /(d{1,2}/){2}d{4}/g, dates = "";
let dateArr = ;
for(let i = 0; i<arr.length; i++){
dates = /(d{1,2}/){2}d{4}/g.exec(arr[i])
dates.pop();
dateArr.push(dates);
}
return dateArr.flat();
}


Although this works, it is clunky and requires I pop() because it will return an array of arrays, ie: ["12/16/1988", "16/"], plus I need to call flat afterwards.



Another option would be to substring the strings, with a given position, where I need to know a regex pattern.



function extractDates2(arr){
let dates = ;
for(let i = 0; i<arr.length; i++){
let begin = regexIndexOf(arr[i], /(d{1,2}/){2}d{4}/g);
let end = regexIndexOf(arr[i], /[0-9] /g, begin) + 1;
dates.push(arr[i].substring(begin, end));
}
return dates;
}


And of course have a regexIndexOf function



function regexIndexOf(str, regex, start = 0){
let indexOf = str.substring(start).search(regex);
indexOf = (indexOf >= 0) ? (indexOf + start) : -1;
return indexOf;
}


Again this function also works, but it seems like an awful lot just to extract something simple. Is there an easier way to extract data into an array?







javascript






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 2 days ago









Travis

667510




667510








  • 3




    Why not use array.map?
    – Henry Howeson
    2 days ago










  • @HenryHoweson .map (alone) won't work if there's more than one date in one of the input strings, eg "1 Ben Howard 12/16/1988 apple 1/10/1999 ", he'd have to flatten it afterwards
    – CertainPerformance
    2 days ago








  • 1




    @CertainPerformance With the regex global flag set it would work fine, also the OP doesn't appear to require that.
    – Henry Howeson
    2 days ago










  • @HenryHoweson Just using the global flag doesn't allow for (concise) extraction of matches from multiple strings into a single array, I thought? What code are you thinking of?
    – CertainPerformance
    2 days ago
















  • 3




    Why not use array.map?
    – Henry Howeson
    2 days ago










  • @HenryHoweson .map (alone) won't work if there's more than one date in one of the input strings, eg "1 Ben Howard 12/16/1988 apple 1/10/1999 ", he'd have to flatten it afterwards
    – CertainPerformance
    2 days ago








  • 1




    @CertainPerformance With the regex global flag set it would work fine, also the OP doesn't appear to require that.
    – Henry Howeson
    2 days ago










  • @HenryHoweson Just using the global flag doesn't allow for (concise) extraction of matches from multiple strings into a single array, I thought? What code are you thinking of?
    – CertainPerformance
    2 days ago










3




3




Why not use array.map?
– Henry Howeson
2 days ago




Why not use array.map?
– Henry Howeson
2 days ago












@HenryHoweson .map (alone) won't work if there's more than one date in one of the input strings, eg "1 Ben Howard 12/16/1988 apple 1/10/1999 ", he'd have to flatten it afterwards
– CertainPerformance
2 days ago






@HenryHoweson .map (alone) won't work if there's more than one date in one of the input strings, eg "1 Ben Howard 12/16/1988 apple 1/10/1999 ", he'd have to flatten it afterwards
– CertainPerformance
2 days ago






1




1




@CertainPerformance With the regex global flag set it would work fine, also the OP doesn't appear to require that.
– Henry Howeson
2 days ago




@CertainPerformance With the regex global flag set it would work fine, also the OP doesn't appear to require that.
– Henry Howeson
2 days ago












@HenryHoweson Just using the global flag doesn't allow for (concise) extraction of matches from multiple strings into a single array, I thought? What code are you thinking of?
– CertainPerformance
2 days ago






@HenryHoweson Just using the global flag doesn't allow for (concise) extraction of matches from multiple strings into a single array, I thought? What code are you thinking of?
– CertainPerformance
2 days ago














4 Answers
4






active

oldest

votes


















12














One option would be to join the strings by a separator that won't be matched, like ,, then just perform the global match to get an array of dates from it:






let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];
const result = infoArr
.join(',')
.match(/(d{1,2}/){2}d{4}/g);
console.log(result);








share|improve this answer

















  • 1




    Works great, and is very concise and easy to reason about.
    – Travis
    2 days ago






  • 4




    This solution appears to be the quickest: jsben.ch/w9geK additionally it has the advantage that it handles array elements without dates (doesn't create null values in the array), do keep in mind however that if you are trying to get the date of a specific element by its' index based on the original array then it may not line up if some elements don't have dates
    – Henry Howeson
    2 days ago








  • 1




    @HenryHoweson It has certain performance to it
    – wscourge
    2 days ago






  • 1




    This doesn't work when the infoArr is empty or none of the strings contains a date, as then match() returns null instead of an array. There's no reason to use join here, map or flatMap are much more reasonable.
    – Bergi
    2 days ago



















16














One approach could be using map() over the elements of the array applying the match on each element, and finally call flat() to get the desired result:






let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];

const result = infoArr.map(o => o.match(/(d{1,2}/){2}d{4}/g)).flat();

console.log(result);





Alternatively, you could use flatMap():






let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];

const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g));

console.log(result);





Also, if you need to remove null values from the final array in the case there are strings without dates, you can apply filter(), like this:



const result = infoArr.map(o => o.match(/(d{1,2}/){2}d{4}/g))
.flat()
.filter(date => date !== null);

const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g))
.filter(date => date !== null);


Example (taking into consideration some conflicting data)






let infoArr = [
"1 Ben Howard 12/16/1988 apple 10/22/1922",
"2 James Smith orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/19075 peach",
"5 Doug Jones 11/10-1975 peach"
];

const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g))
.filter(date => date !== null); /* or filter(date => date) */

console.log(result);








share|improve this answer



















  • 2




    You will end up with null values in the array if any of the lines don't contain dates.
    – Mark Meyer
    2 days ago










  • Thanks for feedback, going to think a workaround for that...
    – Shidersz
    2 days ago






  • 1




    @Shidersz add .filter((e) => {return e}) to the end
    – Henry Howeson
    2 days ago












  • Yeah, thank you, I was writing about that, but I used a more readable syntax
    – Shidersz
    2 days ago






  • 2




    Also, keep in mind that flat and flatMap are still currently "experimental" and subject to change.
    – Drew Reese
    2 days ago



















3















Although this works, it is clunky and requires pop() because it will return an array of arrays, ie: ["12/16/1988", "16/"], plus I need to call flat afterwards.




The regex exec method always has its match in the 0 property (assuming that it matches at all), you can just access that and push it to your array:






let infoArr = [
"1 Ben Howard 12/16/1988 apple",
"2 James Smith 1/10/1999 orange",
"3 Andy Bloss 10/25/1956 apple",
"4 Carrie Walters 8/20/1975 peach",
"5 Doug Jones 11/10/1975 peach"
];

function extractDates(arr){
const dateRegex = /(d{1,2}/){2}d{4}/g;
const dateArr = ;
for (const str of arr){
const date = /(d{1,2}/){2}d{4}/g.exec(str);
dateArr.push(date[0]);
}
return dateArr;
}

console.log(extractDates(infoArr));





(of course you could also do the same in a map callback)






share|improve this answer































    1














    You can use reduce() rather than the loops to pair down the code. Just be careful to keep the null out of the array if there is no match.






    let infoArr = [
    "1 Ben Howard 12/16/1988 apple",
    "2 James Smith 1/10/1999 orange",
    "3 Andy Bloss 10/25/1956 apple",
    "4 Carrie Walters 8/20/1975 peach",
    "5 Doug Jones 11/10/1975 peach"
    ];

    let regex = /(d{1,2}/){2}d{4}/g
    let dates = infoArr.reduce((arr, s) => arr.concat(s.match(regex) || ) , )
    console.log(dates)








    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54000799%2fis-there-a-better-way-to-extract-information-from-a-string%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      12














      One option would be to join the strings by a separator that won't be matched, like ,, then just perform the global match to get an array of dates from it:






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];
      const result = infoArr
      .join(',')
      .match(/(d{1,2}/){2}d{4}/g);
      console.log(result);








      share|improve this answer

















      • 1




        Works great, and is very concise and easy to reason about.
        – Travis
        2 days ago






      • 4




        This solution appears to be the quickest: jsben.ch/w9geK additionally it has the advantage that it handles array elements without dates (doesn't create null values in the array), do keep in mind however that if you are trying to get the date of a specific element by its' index based on the original array then it may not line up if some elements don't have dates
        – Henry Howeson
        2 days ago








      • 1




        @HenryHoweson It has certain performance to it
        – wscourge
        2 days ago






      • 1




        This doesn't work when the infoArr is empty or none of the strings contains a date, as then match() returns null instead of an array. There's no reason to use join here, map or flatMap are much more reasonable.
        – Bergi
        2 days ago
















      12














      One option would be to join the strings by a separator that won't be matched, like ,, then just perform the global match to get an array of dates from it:






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];
      const result = infoArr
      .join(',')
      .match(/(d{1,2}/){2}d{4}/g);
      console.log(result);








      share|improve this answer

















      • 1




        Works great, and is very concise and easy to reason about.
        – Travis
        2 days ago






      • 4




        This solution appears to be the quickest: jsben.ch/w9geK additionally it has the advantage that it handles array elements without dates (doesn't create null values in the array), do keep in mind however that if you are trying to get the date of a specific element by its' index based on the original array then it may not line up if some elements don't have dates
        – Henry Howeson
        2 days ago








      • 1




        @HenryHoweson It has certain performance to it
        – wscourge
        2 days ago






      • 1




        This doesn't work when the infoArr is empty or none of the strings contains a date, as then match() returns null instead of an array. There's no reason to use join here, map or flatMap are much more reasonable.
        – Bergi
        2 days ago














      12












      12








      12






      One option would be to join the strings by a separator that won't be matched, like ,, then just perform the global match to get an array of dates from it:






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];
      const result = infoArr
      .join(',')
      .match(/(d{1,2}/){2}d{4}/g);
      console.log(result);








      share|improve this answer












      One option would be to join the strings by a separator that won't be matched, like ,, then just perform the global match to get an array of dates from it:






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];
      const result = infoArr
      .join(',')
      .match(/(d{1,2}/){2}d{4}/g);
      console.log(result);








      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];
      const result = infoArr
      .join(',')
      .match(/(d{1,2}/){2}d{4}/g);
      console.log(result);





      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];
      const result = infoArr
      .join(',')
      .match(/(d{1,2}/){2}d{4}/g);
      console.log(result);






      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered 2 days ago









      CertainPerformance

      76.9k143862




      76.9k143862








      • 1




        Works great, and is very concise and easy to reason about.
        – Travis
        2 days ago






      • 4




        This solution appears to be the quickest: jsben.ch/w9geK additionally it has the advantage that it handles array elements without dates (doesn't create null values in the array), do keep in mind however that if you are trying to get the date of a specific element by its' index based on the original array then it may not line up if some elements don't have dates
        – Henry Howeson
        2 days ago








      • 1




        @HenryHoweson It has certain performance to it
        – wscourge
        2 days ago






      • 1




        This doesn't work when the infoArr is empty or none of the strings contains a date, as then match() returns null instead of an array. There's no reason to use join here, map or flatMap are much more reasonable.
        – Bergi
        2 days ago














      • 1




        Works great, and is very concise and easy to reason about.
        – Travis
        2 days ago






      • 4




        This solution appears to be the quickest: jsben.ch/w9geK additionally it has the advantage that it handles array elements without dates (doesn't create null values in the array), do keep in mind however that if you are trying to get the date of a specific element by its' index based on the original array then it may not line up if some elements don't have dates
        – Henry Howeson
        2 days ago








      • 1




        @HenryHoweson It has certain performance to it
        – wscourge
        2 days ago






      • 1




        This doesn't work when the infoArr is empty or none of the strings contains a date, as then match() returns null instead of an array. There's no reason to use join here, map or flatMap are much more reasonable.
        – Bergi
        2 days ago








      1




      1




      Works great, and is very concise and easy to reason about.
      – Travis
      2 days ago




      Works great, and is very concise and easy to reason about.
      – Travis
      2 days ago




      4




      4




      This solution appears to be the quickest: jsben.ch/w9geK additionally it has the advantage that it handles array elements without dates (doesn't create null values in the array), do keep in mind however that if you are trying to get the date of a specific element by its' index based on the original array then it may not line up if some elements don't have dates
      – Henry Howeson
      2 days ago






      This solution appears to be the quickest: jsben.ch/w9geK additionally it has the advantage that it handles array elements without dates (doesn't create null values in the array), do keep in mind however that if you are trying to get the date of a specific element by its' index based on the original array then it may not line up if some elements don't have dates
      – Henry Howeson
      2 days ago






      1




      1




      @HenryHoweson It has certain performance to it
      – wscourge
      2 days ago




      @HenryHoweson It has certain performance to it
      – wscourge
      2 days ago




      1




      1




      This doesn't work when the infoArr is empty or none of the strings contains a date, as then match() returns null instead of an array. There's no reason to use join here, map or flatMap are much more reasonable.
      – Bergi
      2 days ago




      This doesn't work when the infoArr is empty or none of the strings contains a date, as then match() returns null instead of an array. There's no reason to use join here, map or flatMap are much more reasonable.
      – Bergi
      2 days ago













      16














      One approach could be using map() over the elements of the array applying the match on each element, and finally call flat() to get the desired result:






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      const result = infoArr.map(o => o.match(/(d{1,2}/){2}d{4}/g)).flat();

      console.log(result);





      Alternatively, you could use flatMap():






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g));

      console.log(result);





      Also, if you need to remove null values from the final array in the case there are strings without dates, you can apply filter(), like this:



      const result = infoArr.map(o => o.match(/(d{1,2}/){2}d{4}/g))
      .flat()
      .filter(date => date !== null);

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g))
      .filter(date => date !== null);


      Example (taking into consideration some conflicting data)






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple 10/22/1922",
      "2 James Smith orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/19075 peach",
      "5 Doug Jones 11/10-1975 peach"
      ];

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g))
      .filter(date => date !== null); /* or filter(date => date) */

      console.log(result);








      share|improve this answer



















      • 2




        You will end up with null values in the array if any of the lines don't contain dates.
        – Mark Meyer
        2 days ago










      • Thanks for feedback, going to think a workaround for that...
        – Shidersz
        2 days ago






      • 1




        @Shidersz add .filter((e) => {return e}) to the end
        – Henry Howeson
        2 days ago












      • Yeah, thank you, I was writing about that, but I used a more readable syntax
        – Shidersz
        2 days ago






      • 2




        Also, keep in mind that flat and flatMap are still currently "experimental" and subject to change.
        – Drew Reese
        2 days ago
















      16














      One approach could be using map() over the elements of the array applying the match on each element, and finally call flat() to get the desired result:






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      const result = infoArr.map(o => o.match(/(d{1,2}/){2}d{4}/g)).flat();

      console.log(result);





      Alternatively, you could use flatMap():






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g));

      console.log(result);





      Also, if you need to remove null values from the final array in the case there are strings without dates, you can apply filter(), like this:



      const result = infoArr.map(o => o.match(/(d{1,2}/){2}d{4}/g))
      .flat()
      .filter(date => date !== null);

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g))
      .filter(date => date !== null);


      Example (taking into consideration some conflicting data)






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple 10/22/1922",
      "2 James Smith orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/19075 peach",
      "5 Doug Jones 11/10-1975 peach"
      ];

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g))
      .filter(date => date !== null); /* or filter(date => date) */

      console.log(result);








      share|improve this answer



















      • 2




        You will end up with null values in the array if any of the lines don't contain dates.
        – Mark Meyer
        2 days ago










      • Thanks for feedback, going to think a workaround for that...
        – Shidersz
        2 days ago






      • 1




        @Shidersz add .filter((e) => {return e}) to the end
        – Henry Howeson
        2 days ago












      • Yeah, thank you, I was writing about that, but I used a more readable syntax
        – Shidersz
        2 days ago






      • 2




        Also, keep in mind that flat and flatMap are still currently "experimental" and subject to change.
        – Drew Reese
        2 days ago














      16












      16








      16






      One approach could be using map() over the elements of the array applying the match on each element, and finally call flat() to get the desired result:






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      const result = infoArr.map(o => o.match(/(d{1,2}/){2}d{4}/g)).flat();

      console.log(result);





      Alternatively, you could use flatMap():






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g));

      console.log(result);





      Also, if you need to remove null values from the final array in the case there are strings without dates, you can apply filter(), like this:



      const result = infoArr.map(o => o.match(/(d{1,2}/){2}d{4}/g))
      .flat()
      .filter(date => date !== null);

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g))
      .filter(date => date !== null);


      Example (taking into consideration some conflicting data)






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple 10/22/1922",
      "2 James Smith orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/19075 peach",
      "5 Doug Jones 11/10-1975 peach"
      ];

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g))
      .filter(date => date !== null); /* or filter(date => date) */

      console.log(result);








      share|improve this answer














      One approach could be using map() over the elements of the array applying the match on each element, and finally call flat() to get the desired result:






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      const result = infoArr.map(o => o.match(/(d{1,2}/){2}d{4}/g)).flat();

      console.log(result);





      Alternatively, you could use flatMap():






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g));

      console.log(result);





      Also, if you need to remove null values from the final array in the case there are strings without dates, you can apply filter(), like this:



      const result = infoArr.map(o => o.match(/(d{1,2}/){2}d{4}/g))
      .flat()
      .filter(date => date !== null);

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g))
      .filter(date => date !== null);


      Example (taking into consideration some conflicting data)






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple 10/22/1922",
      "2 James Smith orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/19075 peach",
      "5 Doug Jones 11/10-1975 peach"
      ];

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g))
      .filter(date => date !== null); /* or filter(date => date) */

      console.log(result);








      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      const result = infoArr.map(o => o.match(/(d{1,2}/){2}d{4}/g)).flat();

      console.log(result);





      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      const result = infoArr.map(o => o.match(/(d{1,2}/){2}d{4}/g)).flat();

      console.log(result);





      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g));

      console.log(result);





      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g));

      console.log(result);





      let infoArr = [
      "1 Ben Howard 12/16/1988 apple 10/22/1922",
      "2 James Smith orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/19075 peach",
      "5 Doug Jones 11/10-1975 peach"
      ];

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g))
      .filter(date => date !== null); /* or filter(date => date) */

      console.log(result);





      let infoArr = [
      "1 Ben Howard 12/16/1988 apple 10/22/1922",
      "2 James Smith orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/19075 peach",
      "5 Doug Jones 11/10-1975 peach"
      ];

      const result = infoArr.flatMap(o => o.match(/(d{1,2}/){2}d{4}/g))
      .filter(date => date !== null); /* or filter(date => date) */

      console.log(result);






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited yesterday

























      answered 2 days ago









      Shidersz

      3,8412528




      3,8412528








      • 2




        You will end up with null values in the array if any of the lines don't contain dates.
        – Mark Meyer
        2 days ago










      • Thanks for feedback, going to think a workaround for that...
        – Shidersz
        2 days ago






      • 1




        @Shidersz add .filter((e) => {return e}) to the end
        – Henry Howeson
        2 days ago












      • Yeah, thank you, I was writing about that, but I used a more readable syntax
        – Shidersz
        2 days ago






      • 2




        Also, keep in mind that flat and flatMap are still currently "experimental" and subject to change.
        – Drew Reese
        2 days ago














      • 2




        You will end up with null values in the array if any of the lines don't contain dates.
        – Mark Meyer
        2 days ago










      • Thanks for feedback, going to think a workaround for that...
        – Shidersz
        2 days ago






      • 1




        @Shidersz add .filter((e) => {return e}) to the end
        – Henry Howeson
        2 days ago












      • Yeah, thank you, I was writing about that, but I used a more readable syntax
        – Shidersz
        2 days ago






      • 2




        Also, keep in mind that flat and flatMap are still currently "experimental" and subject to change.
        – Drew Reese
        2 days ago








      2




      2




      You will end up with null values in the array if any of the lines don't contain dates.
      – Mark Meyer
      2 days ago




      You will end up with null values in the array if any of the lines don't contain dates.
      – Mark Meyer
      2 days ago












      Thanks for feedback, going to think a workaround for that...
      – Shidersz
      2 days ago




      Thanks for feedback, going to think a workaround for that...
      – Shidersz
      2 days ago




      1




      1




      @Shidersz add .filter((e) => {return e}) to the end
      – Henry Howeson
      2 days ago






      @Shidersz add .filter((e) => {return e}) to the end
      – Henry Howeson
      2 days ago














      Yeah, thank you, I was writing about that, but I used a more readable syntax
      – Shidersz
      2 days ago




      Yeah, thank you, I was writing about that, but I used a more readable syntax
      – Shidersz
      2 days ago




      2




      2




      Also, keep in mind that flat and flatMap are still currently "experimental" and subject to change.
      – Drew Reese
      2 days ago




      Also, keep in mind that flat and flatMap are still currently "experimental" and subject to change.
      – Drew Reese
      2 days ago











      3















      Although this works, it is clunky and requires pop() because it will return an array of arrays, ie: ["12/16/1988", "16/"], plus I need to call flat afterwards.




      The regex exec method always has its match in the 0 property (assuming that it matches at all), you can just access that and push it to your array:






      let infoArr = [
      "1 Ben Howard 12/16/1988 apple",
      "2 James Smith 1/10/1999 orange",
      "3 Andy Bloss 10/25/1956 apple",
      "4 Carrie Walters 8/20/1975 peach",
      "5 Doug Jones 11/10/1975 peach"
      ];

      function extractDates(arr){
      const dateRegex = /(d{1,2}/){2}d{4}/g;
      const dateArr = ;
      for (const str of arr){
      const date = /(d{1,2}/){2}d{4}/g.exec(str);
      dateArr.push(date[0]);
      }
      return dateArr;
      }

      console.log(extractDates(infoArr));





      (of course you could also do the same in a map callback)






      share|improve this answer




























        3















        Although this works, it is clunky and requires pop() because it will return an array of arrays, ie: ["12/16/1988", "16/"], plus I need to call flat afterwards.




        The regex exec method always has its match in the 0 property (assuming that it matches at all), you can just access that and push it to your array:






        let infoArr = [
        "1 Ben Howard 12/16/1988 apple",
        "2 James Smith 1/10/1999 orange",
        "3 Andy Bloss 10/25/1956 apple",
        "4 Carrie Walters 8/20/1975 peach",
        "5 Doug Jones 11/10/1975 peach"
        ];

        function extractDates(arr){
        const dateRegex = /(d{1,2}/){2}d{4}/g;
        const dateArr = ;
        for (const str of arr){
        const date = /(d{1,2}/){2}d{4}/g.exec(str);
        dateArr.push(date[0]);
        }
        return dateArr;
        }

        console.log(extractDates(infoArr));





        (of course you could also do the same in a map callback)






        share|improve this answer


























          3












          3








          3







          Although this works, it is clunky and requires pop() because it will return an array of arrays, ie: ["12/16/1988", "16/"], plus I need to call flat afterwards.




          The regex exec method always has its match in the 0 property (assuming that it matches at all), you can just access that and push it to your array:






          let infoArr = [
          "1 Ben Howard 12/16/1988 apple",
          "2 James Smith 1/10/1999 orange",
          "3 Andy Bloss 10/25/1956 apple",
          "4 Carrie Walters 8/20/1975 peach",
          "5 Doug Jones 11/10/1975 peach"
          ];

          function extractDates(arr){
          const dateRegex = /(d{1,2}/){2}d{4}/g;
          const dateArr = ;
          for (const str of arr){
          const date = /(d{1,2}/){2}d{4}/g.exec(str);
          dateArr.push(date[0]);
          }
          return dateArr;
          }

          console.log(extractDates(infoArr));





          (of course you could also do the same in a map callback)






          share|improve this answer















          Although this works, it is clunky and requires pop() because it will return an array of arrays, ie: ["12/16/1988", "16/"], plus I need to call flat afterwards.




          The regex exec method always has its match in the 0 property (assuming that it matches at all), you can just access that and push it to your array:






          let infoArr = [
          "1 Ben Howard 12/16/1988 apple",
          "2 James Smith 1/10/1999 orange",
          "3 Andy Bloss 10/25/1956 apple",
          "4 Carrie Walters 8/20/1975 peach",
          "5 Doug Jones 11/10/1975 peach"
          ];

          function extractDates(arr){
          const dateRegex = /(d{1,2}/){2}d{4}/g;
          const dateArr = ;
          for (const str of arr){
          const date = /(d{1,2}/){2}d{4}/g.exec(str);
          dateArr.push(date[0]);
          }
          return dateArr;
          }

          console.log(extractDates(infoArr));





          (of course you could also do the same in a map callback)






          let infoArr = [
          "1 Ben Howard 12/16/1988 apple",
          "2 James Smith 1/10/1999 orange",
          "3 Andy Bloss 10/25/1956 apple",
          "4 Carrie Walters 8/20/1975 peach",
          "5 Doug Jones 11/10/1975 peach"
          ];

          function extractDates(arr){
          const dateRegex = /(d{1,2}/){2}d{4}/g;
          const dateArr = ;
          for (const str of arr){
          const date = /(d{1,2}/){2}d{4}/g.exec(str);
          dateArr.push(date[0]);
          }
          return dateArr;
          }

          console.log(extractDates(infoArr));





          let infoArr = [
          "1 Ben Howard 12/16/1988 apple",
          "2 James Smith 1/10/1999 orange",
          "3 Andy Bloss 10/25/1956 apple",
          "4 Carrie Walters 8/20/1975 peach",
          "5 Doug Jones 11/10/1975 peach"
          ];

          function extractDates(arr){
          const dateRegex = /(d{1,2}/){2}d{4}/g;
          const dateArr = ;
          for (const str of arr){
          const date = /(d{1,2}/){2}d{4}/g.exec(str);
          dateArr.push(date[0]);
          }
          return dateArr;
          }

          console.log(extractDates(infoArr));






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 2 days ago









          scraaappy

          2,20621326




          2,20621326










          answered 2 days ago









          Bergi

          364k58543868




          364k58543868























              1














              You can use reduce() rather than the loops to pair down the code. Just be careful to keep the null out of the array if there is no match.






              let infoArr = [
              "1 Ben Howard 12/16/1988 apple",
              "2 James Smith 1/10/1999 orange",
              "3 Andy Bloss 10/25/1956 apple",
              "4 Carrie Walters 8/20/1975 peach",
              "5 Doug Jones 11/10/1975 peach"
              ];

              let regex = /(d{1,2}/){2}d{4}/g
              let dates = infoArr.reduce((arr, s) => arr.concat(s.match(regex) || ) , )
              console.log(dates)








              share|improve this answer




























                1














                You can use reduce() rather than the loops to pair down the code. Just be careful to keep the null out of the array if there is no match.






                let infoArr = [
                "1 Ben Howard 12/16/1988 apple",
                "2 James Smith 1/10/1999 orange",
                "3 Andy Bloss 10/25/1956 apple",
                "4 Carrie Walters 8/20/1975 peach",
                "5 Doug Jones 11/10/1975 peach"
                ];

                let regex = /(d{1,2}/){2}d{4}/g
                let dates = infoArr.reduce((arr, s) => arr.concat(s.match(regex) || ) , )
                console.log(dates)








                share|improve this answer


























                  1












                  1








                  1






                  You can use reduce() rather than the loops to pair down the code. Just be careful to keep the null out of the array if there is no match.






                  let infoArr = [
                  "1 Ben Howard 12/16/1988 apple",
                  "2 James Smith 1/10/1999 orange",
                  "3 Andy Bloss 10/25/1956 apple",
                  "4 Carrie Walters 8/20/1975 peach",
                  "5 Doug Jones 11/10/1975 peach"
                  ];

                  let regex = /(d{1,2}/){2}d{4}/g
                  let dates = infoArr.reduce((arr, s) => arr.concat(s.match(regex) || ) , )
                  console.log(dates)








                  share|improve this answer














                  You can use reduce() rather than the loops to pair down the code. Just be careful to keep the null out of the array if there is no match.






                  let infoArr = [
                  "1 Ben Howard 12/16/1988 apple",
                  "2 James Smith 1/10/1999 orange",
                  "3 Andy Bloss 10/25/1956 apple",
                  "4 Carrie Walters 8/20/1975 peach",
                  "5 Doug Jones 11/10/1975 peach"
                  ];

                  let regex = /(d{1,2}/){2}d{4}/g
                  let dates = infoArr.reduce((arr, s) => arr.concat(s.match(regex) || ) , )
                  console.log(dates)








                  let infoArr = [
                  "1 Ben Howard 12/16/1988 apple",
                  "2 James Smith 1/10/1999 orange",
                  "3 Andy Bloss 10/25/1956 apple",
                  "4 Carrie Walters 8/20/1975 peach",
                  "5 Doug Jones 11/10/1975 peach"
                  ];

                  let regex = /(d{1,2}/){2}d{4}/g
                  let dates = infoArr.reduce((arr, s) => arr.concat(s.match(regex) || ) , )
                  console.log(dates)





                  let infoArr = [
                  "1 Ben Howard 12/16/1988 apple",
                  "2 James Smith 1/10/1999 orange",
                  "3 Andy Bloss 10/25/1956 apple",
                  "4 Carrie Walters 8/20/1975 peach",
                  "5 Doug Jones 11/10/1975 peach"
                  ];

                  let regex = /(d{1,2}/){2}d{4}/g
                  let dates = infoArr.reduce((arr, s) => arr.concat(s.match(regex) || ) , )
                  console.log(dates)






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 2 days ago

























                  answered 2 days ago









                  Mark Meyer

                  36.4k32958




                  36.4k32958






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54000799%2fis-there-a-better-way-to-extract-information-from-a-string%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Paul Cézanne

                      UIScrollView CustomStickyHeader Resize height generates problems when scroll is too fast

                      Angular material date-picker (MatDatepicker) auto completes the date on focus out