Home > Software design >  Reduce array in javascript with patern matching
Reduce array in javascript with patern matching

Time:01-05

How would you reduce items from array arr into reducedArray by removing items that first two characters match with strings from array generalCase and if they encountered, then an asterisk is added to indicated that this string was encountered on array arr.

let arr =["ADB", "AB1", "BD1", "BD4", "AB3", "BP9", "BPX","STR", "ABS"]
let generalCase = ["AB", "BD", "BP"]
let reducedArray = []

arr.forEach( item => {
  if (item.startsWith("AB") && !reducedArray.includes("AB*")) {
        reducedArray.push("AB*");
      } else if (item.startsWith("BD") && !reducedArray.includes("BD*")) {
        reducedArray.push("BD*")
      } else if (item.startsWith("BP") && !reducedArray.includes("BP*")) {
        reducedArray.push("BP*")
      } else if (item === "STR") {
        reducedArray.push("STR")
      } else if (!reducedArray.includes(item)) {
        reducedArray.push(item)
      }
})

// Desired result: ["ADB", "AB*", "BD*", "BP*", "STR"]
console.log(reducedArray) // ["ADB", "AB*", "BD*", "BD4", "AB3", "BP*", "BPX", "STR", "ABS"]

CodePudding user response:

You could create a regex from the generalCase array to test if any of the strings in arr start with any of them.

In this case, it creates a regex like this:

/^(?:AB|BD|BP)/

Here's a snippet:

const arr = ["ADB", "AB1", "BD1", "BD4", "AB3", "BP9", "BPX", "STR", "ABS"],
      generalCase = ["AB", "BD", "BP"],
      regex = new RegExp(`^(?:${generalCase.join("|")})`),
      set = new Set;

for (const str of arr) {
  if (regex.test(str))
    set.add(str.slice(0, 2)   "*")
  else
    set.add(str)
}

console.log([...set])

CodePudding user response:

Use reduce():

const arr = ["ADB", "AB1", "BD1", "BD4", "AB3", "BP9", "BPX","STR", "ABS"];
const generalCase = ["AB", "BD", "BP"];

const reducedArray = arr.reduce((p, c) => {
    const firsttwo = c.substring(0,2);
    const toPush = (generalCase.includes(firsttwo)) ? (firsttwo   '*') : c;
    
    if (!p.includes(toPush)) {
        p.push(toPush);
    }
    
    return p;
}, []);

console.log(reducedArray);

Result:

[
  "ADB",
  "AB*",
  "BD*",
  "BP*",
  "STR"
]

CodePudding user response:

Iterate normally, and deduplicate the result in the end:

let arr =["ADB", "AB1", "BD1", "BD4", "AB3", "BP9", "BPX","STR", "ABS"]
let generalCase = ["AB", "BD", "BP"]

let reducedArray = arr.map(item => {
    for (let x of generalCase)
        if (item.startsWith(x))
            return x   '*'
    return item
})


reducedArray = [...new Set(reducedArray)]

console.log(reducedArray)

CodePudding user response:

Here is one more solution.

let reducedArray = [];
let matchWhole = ["STR", "ADB"];
let matchTwo = ["AB", "BD", "BP"];

let twoRegex = new RegExp("^"   matchTwo.join("|"));
let wholeRegex = new RegExp(matchWhole.join("|"));

arr.forEach( item => {
  if(twoRegex.test(item)) {
    let changed  = item.slice(0, 2)   "*";
    if(!reducedArray.includes(changed)){
      reducedArray.push(changed);
    }
  } else if (wholeRegex.test(item)) {
    reducedArray.push(item)
  }
})
  • Related