Home > Back-end >  Less resource intensive way of changing a lot of strings in array JS
Less resource intensive way of changing a lot of strings in array JS

Time:06-15

I'm trying to change a lot of strings and haven't found a "good" way. What I want to do is remove some strings based on different criteria. Exactly:

  1. change 'PD-111 S/A' to 'PD-111' < remove all instances of 'S/A' when the string starts with 'PD-'
  2. change 'KL.OTHERSTUFF' to 'KLOTHERSTUFF' < remove all instances of '.' when the string starts with 'KL'
  3. change 'BD5000-50' to 'BD5000' < remove all instances of '-50' when the string starts with 'BD'

I've tried the .startsWith() and .replace() without any luck and diff iterators like .map to try to create a function to delete based on criteria.

I ended doing a forEach but it's incredibly resource intensive (since the total changes would be around 4k strings). It works but it's really bad I think eventhough I'm a pretty serious noob.

I'll do reproducible code next:

let firstArr = [{
    sku: 'PD-123-A S/A',
    stock: '0'
  },
  {
    sku: 'PD-123-B S/A',
    stock: '1'
  },
  {
    sku: 'PD-123-C S/A',
    stock: '1'
  }
]

let repl = {
  'PD-123-A S/A': 'PD-123-A',
  'PD-123-B S/A': 'PD-123-B',
  'PD-123-C S/A': 'PD-123-C',
}

firstArr.forEach(element => {
  let keys = Object.keys(repl);
  let values = Object.values(repl);
  for (let i = 0; i < keys.length; i  ) {
    if (keys[i] === element.sku) {
      element.sku = values[i];
    }
  }
});
console.log(firstArr);

CodePudding user response:

The most viable solution most probably would be based on a single re-usable mapper function which gets the regex lookup (key-value pairs of a string value's start sequence and its regex based replacement pattern) passed as the map method's optional 2nd thisArg parameter.

The mapping function is implemented generically, thus agnostic to any item property. It operates all of an original item's entries, applies the replacement to just string type values and creates a sanitized shallow copy of the originally processed item. Thus the original data structure does not get mutated.

function createSanitizedEntriesfromBoundRegMap(item) {
  const regMap = this;

  return Object
    .fromEntries(
      Object
        .entries(item)
        .map(([key, value]) => [
          key,
          // target string values only.
          ('string' === typeof value)
            ? value.replace(
                regMap[value.slice(0, 3)] ??
                regMap[value.slice(0, 2)],
                ''
              )
            : value
        ])
    );
}

const sampleArray = [{
  asu: 'BD5000-50',
  sku: 'PD-123-A S/A',
  tvz: 'KL.OTHERSTUFF',
  stock: '0',
}, {
  tvz: 'KL.EVE.R.STUFF',
  sku: 'PD-123-B S/A',
  stock: '1',
}, {
  sku: 'PD-123-C S/A',
  asu: 'BD300-5000-5000',
  stock: '1',
}];

const resultArray = sampleArray
  .map(createSanitizedEntriesfromBoundRegMap, {
    // provide the regex lookup as `thisArg`.
    'PD-': /\s*S\/A\s*/g,
    KL: /\. /g,
    BD: /-50/g,
  });

console.log({
  resultArray,
  sampleArray,
});
.as-console-wrapper { min-height: 100%!important; top: 0; }

CodePudding user response:

I don't know much as of yet but I didn't try to use .filter and .map to do something similar, trying to go more the route of .startsWith().replace() but I can't really make it work.

While trying to reproduce what I couldn't do, I actually did it. I'll still post with the answer and maybe hope there's a better way to do this.

SOLVED

let firstArr = [{
    sku: 'PD-123-A S/A',
    stock: '0'
  },
  {
    sku: 'PD-123-B S/A',
    stock: '1'
  },
  {
    sku: 'PD-123-C S/A',
    stock: '2'
  },
  {
    sku: 'PD-123-D',
    stock: '3'
  },
  {
    sku: 'BD111-50',
    stock: '0'
  },
  {
    sku: 'BD222-50',
    stock: '1'
  },
  {
    sku: 'BD333-50',
    stock: '2'
  },
  {
    sku: 'BD444',
    stock: '3'
  },
  {
    sku: 'KL.111',
    stock: '0'
  },
  {
    sku: 'KL.222',
    stock: '1'
  },
  {
    sku: 'KL.333',
    stock: '2'
  },
  {
    sku: 'KL444',
    stock: '3'
  }
]

let b = firstArr.map(e => {
  if (e.sku.startsWith('PD-')) {
    return ({
      sku: e.sku.replace('S/A','').trim(),
      stock: e.stock
    })
  } if (e.sku.startsWith('BD')){
    return ({
      sku: e.sku.replace('-50','').trim(),
      stock: e.stock
    })
  } if (e.sku.startsWith('KL')) {
    return ({
      sku: e.sku.replace('.','').trim(),
      stock: e.stock
    })
  } 
})

console.log(b)

  • Related