Is there any convenient way to replace the content of an array, AND keep a reference to it? I don't want to replace the array like this:
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);
This way arr1
has the content of arr2
, but I loose the reference in referenceToArr1
, because it still points to the original arr1
.
With this way, I don't loose the reference:
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)
The drawback here is, that I have to empty arr1.length = 0
, iterate over every element of arr2
and push it to arr1
by hand.
My questions are:
Background:
I have an AngularJS app with a service. Inside this service, I have an array to keep all the elements loaded from the server. The data from the service get's bind to a controller and is used in a view. When the data from the service get's change (e.g. a refetch happens), I want to auto update my controllers vars and the view it is bind to.
Here is a Plunker: http://plnkr.co/edit/8yYahwDO6pAuwl6lcpAS?p=preview
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;
}
}
})
And the view:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="[email protected]" src="https://code.angularjs.org/1.2.16/angular.js" data-semver="1.2.16"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<ul>
<li ng-repeat="d in data">{{d}}</li>
</ul>
3 refetches every second
</body>
</html>
Replace an Element in an Array using Array.Use the indexOf() method to get the index of the element you want to replace. Call the Array. splice() method to replace the element at the specific index. The array element will get replaced in place.
To change the value of an object in an array:Use the Array. map() method to iterate over the array. Check if each object is the one to be updated. Use the spread syntax to update the value of the matching object.
The . splice() method lets you replace multiple elements in an array with one, two, or however many elements you like.
What about this:
// 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);
See:
You can use splice to replace the content of arr1
with the one of arr2
:
[].splice.apply(arr1, [0, arr1.length].concat(arr2));
This way, all references to arr1
would be correctly updated as this would be the same array with a new content.
As you see, that's possible and easy. But there's normally no reason to do this in a well designed program. If the reason is that you're passing an array to different places, then perhaps you should consider embedding this array in an object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With