One liner javascript function to edit value of specific property from array of objects

Viewed 54

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');

5 Answers

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)

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

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)

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;
  });
}

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

Related