简体   繁体   中英

(AngularJS) Most efficient way to replace values in array globally

I want to replace all values in my array, here's the code:

var jsonImg = [
{"url":"https://example.amazonaws.com/images-lib/1496846856-Retina 01.jpg"},
{"url":"https://example.amazonaws.com/images-lib/1496846856-Retina 02.jpg"},
{"url":"https://example.amazonaws.com/images-lib/1496846856-Retina 03.jpg"}
];

var imgUrl = JSON.stringify(jsonImg);
var oldString = imgUrl;
var newString = oldString.replace(/https:\/\/example.amazonaws.com\/images-lib\//g,"cordova.url/");

$scope.Images = JSON.parse(newString);

But I think JSON.Stringfly and JSON.Parse are a bit redundant here, Do you think this is the most efficient way to replace all of the value JSON.Stringfly and JSON.Parse? are there some other alternative to do this? Please check the fiddle here: https://jsfiddle.net/dedenbangkit/zu7utr6a/3/

You are right. There is no need to convert to string and back. Though when it comes to small number of values in array, it wouldn't matter much in terms of efficiency. But, why convert to string and back when you can have such powerful functions for array itself.

Something like:

$scope.Images = jsonImg.map(function(obj) {
  obj.url = "cordova.url" + obj.url.substr(obj.url.lastIndexOf("/"))
  return obj;
});

updated fiddle

In my understanding, repeating cdn path in all image urls is redundant. You should create another variable that will hold this path and when you need to use it, just concat both strings. This way, you can easily change cdn path and you do not need to process.

Sample

For demonstration purpose, I have used Math.random , but you can put your condition.

 function ImgCtrl($scope) { var s3 = "https://s3-ap-southeast-1.amazonaws.com/publixx-statics/images-lib/"; var cordava = "cordova.url/"; var urls = [{ "url": "1496846856-Retina 01.jpg" }, { "url": "1496846856-Retina 02.jpg" }, { "url": "1496846856-Retina 03.jpg" }] $scope.path = Math.floor(Math.random() * 100) % 2 === 0 ? s3 : cordava; $scope.Images = urls; console.log($scope.Images[0].url) } 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script> <div ng-app> <div ng-controller="ImgCtrl"> <ul> <li ng-repeat="Image in Images"> {{path}}{{Image.url}} </li> </ul> </div> </div> 


As per our discussion, you can have 2 options:

  • Sample 1 is more useful when your flag is more dynamic and will change very frequently.
  • Sample 2 is more useful in cases your flag will only have 1 value for 1 cycle. Something like A/B testing. Since it will remain same always for a cycle, computing again makes no sense. Just save a processed value. This will also encapsulate urls in scope and it will not be available outside, so adds security.
// Sample 1
var flag = Math.floor(Math.random() * 100) % 2 === 0;

function getImagePath(image) {
  var s3 = "https://s3-ap-southeast-1.amazonaws.com/publixx-statics/images-lib/";
  var cordava = "cordova.url/";
  return (flag ? s3 : cordava) + image;
}

// Usage:

var url = getImagePath(imageUrl)

// Sample 2
var path = (function() {
  var s3 = "https://s3-ap-southeast-1.amazonaws.com/publixx-statics/images-lib/";
  var cordava = "cordova.url/";
  return flag ? s3 : cordava;
})()

var url = path + imageUrl;
var jsonImg = [
  { 'url': 'https://example.amazonaws.com/images-lib/1496846856-Retina 01.jpg' },
  { 'url': 'https://example.amazonaws.com/images-lib/1496846856-Retina 02.jpg' },
  { 'url': 'https://example.amazonaws.com/images-lib/1496846856-Retina 03.jpg' },
];

jsonImg.map(function(image) {
  var split = image.url.split('/');
  var fileName = split[split.length - 1];
  image.url = 'cordova.url/' + fileName;
});

This will mutate all strings in your jsonImg array, replacing the https://example.amazonaws.com/images-lib/ URL's with cordova.url/ .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM