【问题标题】:(AngularJS) Most efficient way to replace values in array globally(AngularJS)全局替换数组中值的最有效方法
【发布时间】:2017-06-08 06:38:45
【问题描述】:

我想替换数组中的所有值,代码如下:

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

但我认为 JSON.Stringfly 和 JSON.Parse 在这里有点多余,你认为这是替换所有值 JSON.Stringfly 和 JSON.Parse 的最有效方法吗?还有其他选择吗?请在这里检查小提琴: https://jsfiddle.net/dedenbangkit/zu7utr6a/3/

【问题讨论】:

  • 只是一个指针,JSON.stringify 将删除对象中的所有函数。

标签: javascript angularjs arrays json


【解决方案1】:

据我了解,在所有图片 url 中重复 cdn 路径是多余的。您应该创建另一个变量来保存此路径,当您需要使用它时,只需连接两个字符串。这样,您可以轻松更改cdn路径,无需处理。

示例

出于演示目的,我使用了Math.random,但您可以输入您的条件。

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>

根据我们的讨论,您可以有两种选择:

  • 当您的标志更加动态并且会非常频繁地更改时,示例 1 更有用。
  • 示例 2 在您的标志在 1 个周期内只有 1 个值的情况下更有用。类似于 A/B 测试。由于它在一个周期内始终保持不变,因此再次计算毫无意义。只需保存处理后的值。这也会将 url 封装在范围内,并且在外部不可用,因此增加了安全性。
// 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;

【讨论】:

  • 哇,谢谢,我想你可以回答我的下一个问题。就我而言,我有两种选择可以离线和在线阅读。假设我有带有“blogId”对象的 $localStorage 与“下载”值一起存储。如何切换这两个功能?一个有cdn路径和其他没有cdn路径的功能?
  • 在这种情况下,创建一个检查标志值的函数。根据这个标志值,要么从 localStorage 读取它,要么使用硬编码的 CDN url 并返回它。理想情况下,这是一个配置参数,应该处理一次。你可以做类似$scope.path = (function(){ logic... })()
  • 那么你觉得哪一个会更有效率呢?函数(路径)之类的东西?或函数(在线或离线)是否在函数内?
【解决方案2】:
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;
});

这将改变您的jsonImg 数组中的所有字符串,将https://example.amazonaws.com/images-lib/ URL 替换为cordova.url/

【讨论】:

    【解决方案3】:

    你是对的。无需转换为字符串并返回。尽管当涉及到数组中的少量值时,在效率方面并不重要。但是,既然数组本身可以拥有如此强大的功能,为什么要转换为字符串并返回呢。

    类似:

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

    updated fiddle

    【讨论】:

    • 那么哪一种是有效的方式呢?使用 map 函数循环或将其变为字符串然后数组
    • @Mr_Perfect 我还没有检查过 jsperf 或类似的东西。但我总是建议尽可能使用数组函数而不是字符串转换。正如我在更新的答案中提到的那样,对于这么少的值来说,这并不重要
    猜你喜欢
    • 1970-01-01
    • 2021-07-17
    • 2012-06-22
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    • 1970-01-01
    • 2011-01-05
    • 1970-01-01
    相关资源
    最近更新 更多