替换数组内容的简短方法

时间:2014-05-06 05:37:08

标签: javascript arrays angularjs underscore.js

有没有方便的方法来替换数组的内容,并保留对它的引用?我不想像这样替换数组:

var arr1 = [1,2,3];
var referenceToArr1 = arr1;
var arr2 = [4,5,6];

arr1 = arr2;
// logs: [4,5,6] false
console.log(arr1, arr1===referenceToArr1);
// logs [1,2,3]
console.log(referenceToArr1);

这种方式arr1的内容为arr2,但我在referenceToArr1中放弃了引用,因为它仍然指向原始 {{1} }。

通过这种方式,我没有放弃参考:

arr1

这里的缺点是,我必须清空var arr1 = [1,2,3]; var referenceToArr1 = arr1; var arr2 = [4,5,6]; arr1.length = 0; for (var i = 0; i < arr2.length; i++) { arr1.push(arr2[i]); } // logs: [4,5,6] true console.log(arr1, arr1===referenceToArr1); // logs: [4,5,6] console.log(referenceToArr1) ,迭代arr1.length = 0的每个元素并手动将其推送到arr2

我的问题是:

  • 当然,我可以为此写一个帮手,但最有效的方法是什么?
  • 是否有一种简短的,香草的javascript方式,这样做(也许是一个班轮?)
  • 我也在使用underscore.js,但还没有找到解决此类问题的方法。有没有办法用underscore.js做到这一点?

背景

我有一个带服务的AngularJS应用程序。在这个服务中,我有一个数组来保持从服务器加载所有元素。来自服务get的数据绑定到控制器并在视图中使用。当来自服务的数据发生变化(例如重新发生)时,我想自动更新我的控制器变量及其绑定的视图。

这是一个Plunker:http://plnkr.co/edit/8yYahwDO6pAuwl6lcpAS?p=preview

arr1

观点:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, myService) {
  $scope.name = 'World';
  myService.fetchData().then(function(data) {
    console.log(data)
    $scope.data = data;
  })
});

app.service('myService', function($timeout, $q) {
  var arr;
  var deferred;

  var loadData = function() {
    // here comes some data from the server
    var serverData = [1,2,3];
    arr = serverData;
    deferred.resolve(arr);

    // simulate a refetch of the data
    $timeout(function() {
      var newServerData = [4,5,6];
      // this won't work, because MainCtrl looses it's reference
      // arr = newServerData;
    }, 1000);

    $timeout(function() {
      var newServerData = [7,8,9];
      arr.length = 0;
      [].push.apply(arr, newServerData);
    }, 2000);

    $timeout(function() {
      var newServerData = [10,11,12];
      [].splice.apply(arr, [0, arr.length].concat(newServerData));
    }, 3000);
  }

  return {
    fetchData: function() {
      deferred = $q.defer();

      loadData();

      return deferred.promise;
    }
  }
})

3 个答案:

答案 0 :(得分:11)

这个怎么样:

// 1. reset the array while keeping its reference
arr1.length = 0;
// 2. fill the first array with items from the second
[].push.apply(arr1, arr2);

请参阅:

  1. How to empty an array in JavaScript?
  2. .push() multiple objects into JavaScript array returns 'undefined'

答案 1 :(得分:4)

您可以使用splicearr1的内容替换为arr2的内容:

[].splice.apply(arr1, [0, arr1.length].concat(arr2));

这样,对arr1的所有引用都将被正确更新,因为这将是具有新内容的相同数组。

如你所见,这是可能的,也很容易。但通常没有理由在精心设计的程序中这样做。如果原因是你将数组传递到不同的地方,那么也许你应该考虑将这个数组嵌入到一个对象中。

答案 2 :(得分:0)

这将合并两个数组中来自第二个数组的持久项

[...arr2, ...arr1.slice(arr2.length)]