9

Is there an easy way to replace all appearances of an primitive in an array with another one. So that ['a', 'b', 'a', 'c'] would become ['x', 'b', 'x', 'c'] when replacing a with x. I'm aware that this can be done with a map function, but I wonder if have overlooked a simpler way.

4
  • I think the purpose of a library like Lo-Dash is not to enable you to write the most code-golfy solution you can possibly write, but to write the most natural and idiomatic solution. And what could be more natural and idiomatic than map() in this case? It's the perfect tool for the job. Commented Nov 8, 2013 at 14:46
  • @Tomalak _(array).filter('someKey').replace('a', 'x') looks very natural to me Commented Nov 8, 2013 at 14:57
  • 1
    But that would not be logical - I would expect an operation named "filter" to reduce number of elements in the input. Also: It's not about the looks. It's about the operation you want to perform on the data, and to me that is "mapping a list of N values a list of N values (some of which by accident happen to be the same as the input)". Commented Nov 8, 2013 at 15:08
  • Use findIndex from Lodash then replace the element at the found index Commented Mar 9, 2019 at 7:23

5 Answers 5

11

In the specific case of strings your example has, you can do it natively with:

myArr.join(",").replace(/a/g,"x").split(",");

Where "," is some string that doesn't appear in the array.

That said, I don't see the issue with a _.map - it sounds like the better approach since this is in fact what you're doing. You're mapping the array to itself with the value replaced.

_.map(myArr,function(el){
     return (el==='a') ? 'x' : el;
})
Sign up to request clarification or add additional context in comments.

3 Comments

The question was about primitives not just strings. Also I want to use lodash, as this will be one step in a longer chain, where the array data is manipulated in.
@AndreasKöberle First of all using a particular library is a mean and not a goal. Second of all - in that case _.map is what you're looking for, underscore/lodash has no specific replace/swap functionality on collections, you can add it to the lodash prototype yourself if you'd like.
_.map is really fit to this use case, there's no need to look for anything else.
3

I don't know about "simpler", but you can make it reusable

function swap(ref, replacement, input) {
    return (ref === input) ? replacement : input;
}

var a = ['a', 'b', 'a', 'c'];

_.map(a, _.partial(swap, 'a', 'x'));

Comments

3

If the array contains mutable objects, It's straightforward with lodash's find function.

  var arr = [{'a':'a'}, {'b':'b'},{'a':'a'},{'c':'c'}];    

  while(_.find(arr, {'a':'a'})){
    (_.find(arr, {'a':'a'})).a = 'x';
  }


console.log(arr); // [{'a':'x'}, {'b':'b'},{'a':'x'},{'c':'c'}]

Comments

1

Another simple solution. Works well with arrays of strings, replaces all the occurrences, reads well.

var arr1 = ['a', 'b', 'a', 'c'];
var arr2 = _.map(arr1, _.partial(_.replace, _, 'a', 'd'));
console.log(arr2); // ["d", "b", "d", "c"]

Comments

0

A replace method like this one could work:

const replacer = (contextArray, itemToReplace, replaceWith) => _.map(
  contextArray,
  (n) => n === itemToReplace ? replaceWith : n
)
console.log(replacer(['a', 'b', 'a', 'c'], "a", "x"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.19/lodash.min.js"></script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.