Use [].Replace to Make a Copy of an Array

Use [].replace to make a copy of an array

This is the tricky concept of mutability in ruby. In terms of core objects, this usually comes up with arrays and hashes. Strings are mutable as well, but this can be disabled with a flag at the top of the script. See What does the comment "frozen_string_literal: true" do?.

In this case, you can call dup, deep_dup, clone easily to the same effect as replace:

['some', 'array'].dup
['some', 'array'].deep_dup
['some', 'array'].clone
Marshal.load Marshal::dump(['some', 'array'])

In terms of differences, dup and clone are the same except for some nuanced details - see What's the difference between Ruby's dup and clone methods?

The difference between these and deep_dup is that deep_dup works recursively. For example if you dup a nested array, the inner array will not be cloned:

  a = [[1]]
b = a.clone
b[0][0] = 2
a # => [[2]]

The same thing happens with hashes.

Marshal.load Marshal::dump <object> is a general approach to deep cloning objects, which, unlike deep_dup, is in ruby core. Marshal::dump returns a string so it can be handy in serializing objects to file.

If you want to avoid unexpected errors like this, keep a mental index of which methods have side-effects and only call those when it makes sense to. An explanation point at the end of a method name indicates that it has side effects, but others include unshift, push, concat, delete, and pop. A big part of fuctional programming is avoiding side effects. You can see https://www.sitepoint.com/functional-programming-techniques-with-ruby-part-i/

Copy array by value

Use this:

let oldArray = [1, 2, 3, 4, 5];

let newArray = oldArray.slice();

console.log({newArray});

Replacing objects in array

You can use Array#map with Array#find.

arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);

var arr1 = [{    id: '124',    name: 'qqq'}, {    id: '589',    name: 'www'}, {    id: '45',    name: 'eee'}, {    id: '567',    name: 'rrr'}];
var arr2 = [{ id: '124', name: 'ttt'}, { id: '45', name: 'yyy'}];
var res = arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);
console.log(res);

Replace element at specific position in an array without mutating it

You can use Object.assign:

Object.assign([], array, {2: newItem});

Copying of an array of objects to another Array without object reference in javascript(Deep copy)

Let me understand: you don't want just have a new array, but you want to create a new instance for all objects are present in the array itself? So if you modify one of the objects in the temp array, that changes is not propagated to the main array?

If it's the case, it depends by the values you're keeping in the main array. If these objects are simple objects, and they can be serialized in JSON, then the quickest way is:

var tempArray = JSON.parse(JSON.stringify(mainArray));

If you have more complex objects (like instances created by some your own constructors, html nodes, etc) then you need an approach ad hoc.

Edit:

If you don't have any methods on your newObjectCreation, you could use JSON, however the constructor won't be the same. Otherwise you have to do the copy manually:

var tempArray = [];
for (var i = 0, item; item = mainArray[i++];) {
tempArray[i] = new newObjectCreation(item.localIP, item.remoteIP, item.areaId);
}

How to replace item in array?

var index = items.indexOf(3452);

if (index !== -1) {
items[index] = 1010;
}

Also it is recommend you not use the constructor method to initialize your arrays. Instead, use the literal syntax:

var items = [523, 3452, 334, 31, 5346];

You can also use the ~ operator if you are into terse JavaScript and want to shorten the -1 comparison:

var index = items.indexOf(3452);

if (~index) {
items[index] = 1010;
}

Sometimes I even like to write a contains function to abstract this check and make it easier to understand what's going on. What's awesome is this works on arrays and strings both:

var contains = function (haystack, needle) {
return !!~haystack.indexOf(needle);
};

// can be used like so now:
if (contains(items, 3452)) {
// do something else...
}

Starting with ES6/ES2015 for strings, and proposed for ES2016 for arrays, you can more easily determine if a source contains another value:

if (haystack.includes(needle)) {
// do your thing
}

Cloning an array in Javascript/Typescript

Clone an object:

const myClonedObject = Object.assign({}, myObject);

Clone an Array:

  • Option 1 if you have an array of primitive types:

const myClonedArray = Object.assign([], myArray);

  • Option 2 - if you have an array of objects:
const myArray= [{ a: 'a', b: 'b' }, { a: 'c', b: 'd' }];
const myClonedArray = [];
myArray.forEach(val => myClonedArray.push(Object.assign({}, val)));

Duplicating a Ruby array of strings

Your second solution can be shortened to arr2 = arr.map do |e| e.dup end (unless you actually need the behaviour of clone, it's recommended to use dup instead).

Other than that your two solutions are basically the standard solutions to perform a deep copy (though the second version is only one-level deep (i.e. if you use it on an array of arrays of strings, you can still mutate the strings)). There isn't really a nicer way.

Edit: Here's a recursive deep_dup method that works with arbitrarily nested arrays:

class Array
def deep_dup
map {|x| x.deep_dup}
end
end

class Object
def deep_dup
dup
end
end

class Numeric
# We need this because number.dup throws an exception
# We also need the same definition for Symbol, TrueClass and FalseClass
def deep_dup
self
end
end

You might also want to define deep_dup for other containers (like Hash), otherwise you'll still get a shallow copy for those.

How to replace elements in array with elements of another array

You can use the splice method to replace part of an array with items from another array, but you have to call it in a special way as it expects the items as parameters, not the array.

The splice method expects parameters like (0, anotherArr.Length, 1, 2, 3), so you need to create an array with the parameters and use the apply method to call the splice method with the parameters:

Array.prototype.splice.apply(arr, [0, anotherArr.length].concat(anotherArr));

Example:

var arr = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
var anotherArr = [ 1, 2, 3 ];

Array.prototype.splice.apply(arr, [0, anotherArr.length].concat(anotherArr));

console.log(arr);

Output:

[ 1, 2, 3, 'd', 'e', 'f', 'g', 'h', 'i', 'j']

Demo: http://jsfiddle.net/Guffa/bB7Ey/



Related Topics



Leave a reply



Submit