2

Say, I have array of objects:

arr = [
    {path: 'mexico', name: 'mexico'},
    {path: 'brazil', name: 'brazil'},
    {path: 'netherlands', name: 'netherlands'}
];

What I want to achieve:

prefix = 'country/'
arr = [
    {path: 'country/mexico', name: 'mexico'},
    {path: 'country/brazil', name: 'brazil'},
    {path: 'country/netherlands', name: 'netherlands'}
];

Is there a one liner javascript function that append the prefix country/ into the path property of all objects in the array?

perhaps, something like this: arr.append(prefix, arr, 'path');

jthinam
  • 279
  • 2
  • 7

5 Answers5

2

As mdn says about map() function:

The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

So the code would be looked like that:

arr = arr.map(s => ({...s, path: 'country/' + s.path}))

An example:

let arr = [
    {path: 'mexico', name: 'mexico'},
    {path: 'brazil', name: 'brazil'},
    {path: 'netherlands', name: 'netherlands'}
];

arr = arr.map(s => ({...s, path: 'country/' + s.path}))
console.log(arr)
StepUp
  • 36,391
  • 15
  • 88
  • 148
2

You could use a forEach and a concat:

arr = [
    {path: 'mexico', name: 'mexico'},
    {path: 'brazil', name: 'brazil'},
    {path: 'netherlands', name: 'netherlands'}
];
prefix = 'country/';
arr.forEach(x => x.path = prefix.concat(x.path));
console.log(arr);

EDIT:

Following what @MaikLowrey suggested on comment and reading this answer, + operator to concat strings has better performance and memory allocation compared to concat operator.

So the optimized solution is:

    arr = [
        {path: 'mexico', name: 'mexico'},
        {path: 'brazil', name: 'brazil'},
        {path: 'netherlands', name: 'netherlands'}
    ];
    prefix = 'country/';
    arr.forEach(x => x.path = prefix + x.path);
    console.log(arr);
Giovanni Esposito
  • 10,696
  • 1
  • 14
  • 30
  • 1
    Good solution but concat decrease your perfomance. better use `+`. `x.path = prefix + x.path)` – Maik Lowrey Apr 15 '22 at 07:40
  • 1
    @MaikLowrey this is an intersting point of discussion. Unfortunately I'm not so expert to say which is the faster one. I read [this](https://stackoverflow.com/a/47628/13897065) answer. Is quite old but it was updated on 2017. Before that date seems that `concat` works better with few strings, but on 2017 update seems that `+` got a small advantage in terms of performance and memory allocation. So yes, you are right. i will update my answer. – Giovanni Esposito Apr 15 '22 at 08:02
  • 1
    Thank you for your feedback. It was only a hint. But if you work on scaled application it could be a point for optimization. ... and i like to discuss programming :-) Greetings & +1up! – Maik Lowrey Apr 15 '22 at 08:29
0

arr = [
    {path: 'mexico', name: 'mexico'},
    {path: 'brazil', name: 'brazil'},
    {path: 'netherlands', name: 'netherlands'}
];

prefix = "country/"

arr.forEach(entry => entry.path = prefix + entry.path)
console.log(arr)
Vincent
  • 453
  • 3
  • 6
0

The easiest way to do this would to use Array#forEach or Array#map like so:

var prefix = 'country/';
var arr = [{
    path: 'mexico',
    name: 'mexico'
  },
  {
    path: 'brazil',
    name: 'brazil'
  },
  {
    path: 'netherlands',
    name: 'netherlands'
  }
];
arr.forEach(item => item.path = prefix + item.path);
console.log(arr);

You could also create your own somewhat generic function to do this for you

var prefix = 'country/';
var arr = [{
    path: 'mexico',
    name: 'mexico'
  },
  {
    path: 'brazil',
    name: 'brazil'
  },
  {
    path: 'netherlands',
    name: 'netherlands'
  }
];
console.log(listPrepend(arr, "path", prefix));


function listPrepend(list, property, prefix) {
  return list.map(function(item) {
    item[property] = prefix + item[property];
    return item;
  });
}

You could also add some more logic to it

var prefix = 'country/';
var arr = [{
    path: 'mexico',
    name: 'mexico',
    nested: {
      path: 'mexico'
    }
  },
  {
    path: 'brazil',
    name: 'brazil',
    nested: {
      path: 'brazil'
    }
  },
  {
    path: 'netherlands',
    name: 'netherlands',
    nested: {
      path: 'netherlands'
    }
  }
];
console.log(listPrepend(arr, "nested.path", prefix));


function listPrepend(list, propertyPath, prefix) {
  return list.map(function(item) {
    propertyPath.split(".").reduce(function(result, property, index, full) {
      var innerValue = result[property];
      if (index === full.length - 1) {
        result[property] = prefix + innerValue;
        return result;
      }
      return innerValue;
    }, item);
    return item;
  });
}
nick zoum
  • 7,216
  • 7
  • 36
  • 80
0

All conceivable possibilities are already listed. Therefore here is a slightly different approach. Why fill your existing array with unnecessary redudant strings, when you can add the string in front in your loop. The advantage is not obvious in this example. If you have an array of more than just 195 countries, then you have unnecessarily included x times the prefix. Unnecessary power! ;-)

const arr = [
    {path: 'mexico', name: 'mexico'},
    {path: 'brazil', name: 'brazil'},
    {path: 'netherlands', name: 'netherlands'}
  ];
const prefix = 'country/';

function setPath(row) {
  return  prefix + row.path;  
}

// in the loop
arr.forEach(row => console.log(setPath(row)))

// by index
console.log(`Here is the link to ${arr[1].name}: ${setPath(arr[1])}`)
Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79