Sachihiro
Sachihiro

Reputation: 1781

Reduce array in javascript with patern matching

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"]

Upvotes: 0

Views: 72

Answers (3)

adiga
adiga

Reputation: 35222

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])

Upvotes: 1

0stone0
0stone0

Reputation: 43972

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"
]

Upvotes: 0

gog
gog

Reputation: 11347

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)

Upvotes: 0

Related Questions