Homelab, Linux, JS & ABAP (~˘▾˘)~
 

[JavaScript] Clone an object containing a file as ArrayBuffer

Use the build in function structuredClone() to copy all kind of complex JS types.

Official documentation: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types

Comparison to other copy techniques like spread or json.stringify: https://www.builder.io/blog/structured-clone

[JavaScript] Arrays

These are my notes while doing the course JavaScript Algorithms and Data Structures on https://www.freecodecamp.org. I highly recommend it if you prefer to try things directly rather than watching videos.


Note: In JavaScript arrays are technically a type of object. Therefore arrays are also capable of storing complex objects.

Array functions to manipulate arrays:

/* Modify Array Data with Indexes */
var myArray = [50,40,30];
myArray[0] = 15; // equals [15,40,30]


/* Access Multi-Dimensional Arrays with Indexes */
var myArray = [
  [1,2,3],
  [4,5,6],
  [7,8,9],
  [[10,11,12], 13, 14]
];
myArray[3]; // equals [[10,11,12], 13, 14]
myArray[3][0]; // equals [10,11,12]
myArray[3][0][1]; // equals 11


/* Manipulate Arrays with push() -> adding to the end */
var myArray = [1,2,3];
myArray.push(4); // myArray is now [1,2,3,4]


/* Manipulate Arrays with pop() -> removing last element */
var threeArr = [1, 4, 6];
var oneDown = threeArr.pop();
console.log(oneDown); // Returns 6
console.log(threeArr); // Returns [1, 4]


/* Manipulate Arrays with shift() -> removing first element */
var myArray = ["Stimpson", "J", ["cat"]];
var removedFromOurArray = myArray.shift();
console.log(removedFromOurArray); // Returns "Stimpson"
console.log(myArray); // Returns ["J", ["cat"]]


/* Manipulate Arrays with unshift() -> adding to the beginning */
var myArray = ["Stimpson", "J", "cat"];
myArray.shift(); // myArray now equals ["J", "cat"]
myArray.unshift("Happy"); // myArray now equals ["Happy", "J", "cat"]


/* Manipulate Arrays with concat() -> combine arrays into a new one without mutating the original arrays. */
var firstArray = [1, 2, 3];
var secondArray = [4, 5, 6];
var thirdArray = firstArray.concat(secondArray); // thirdArray now equals [ 1, 2, 3, 4, 5, 6 ]
/* Also useable to clone an array (will do a copy by reference!) */
var fourthArray = [].concat(firstArray); // FourthArray now equals [1, 2, 3]


/* Remove & Add Items using splice() -> remove any number of consecutive elements from anywhere in an array. */
/* First parameter: index */
/* Second parameter: number of elements to delete */
let array = ['today', 'was', 'not', 'so', 'great'];
array.splice(2, 2);  // array now equals ['today', 'was', 'great']
/* Third parameter: add elements to the array. Useful for quickly switching out an element, or a set of elements, for another. */
const numbers = [10, 11, 12, 12, 15];
numbers.splice(3, 1, 13, 14); // returns [ 10, 11, 12, 13, 14, 15 ]


/* Sort numbers in an array: array.sort(compareFunction) */ 
arr.sort((a, b) => a-b); // ascending
arr.sort((a, b) => b-a); // descending

Array functions that does not mutate the original array:

/* Copy Array Items Using slice() -> copies or extracts a given number of elements to a new array, leaving the array it is called upon untouched */
let weatherConditions = ['rain', 'snow', 'sleet', 'hail', 'clear'];
let todaysWeather = weatherConditions.slice(1, 3); // todaysWeather equals ['snow', 'sleet'];


/* Copy an Array with the Spread Operator -> allows to easily copy all of an array's elements. Syntax: ... */
let thisArray = [true, true, undefined, false, null];
let thatArray = [...thisArray]; // thatArray equals [true, true, undefined, false, null];


/* Combine Arrays with the Spread Operator */
let fragment = ['to', 'code'];
let sentence = ['learning', ...fragment, 'is', 'fun']; // sentence equals ['learning', 'to', 'code', 'is', 'fun']


/* The reduce() method reduces the array to a single value. It executes a provided function for each value of the array (from left-to-right).*/
/* First parameter: The initialValue, or the previously returned value of the function */
/* Second parameter: The value of the current element */
/* 0 is set as initialValue */
const args = [2, 4, 2];
const arraySum = args.reduce((sum, currentNum) => sum + currentNum, 0); // returns 8 


/* map() iterates over each item in an array and returns a new array containing the results of calling the callback function on each element */
const users = [
  { name: 'John', age: 34 },
  { name: 'Amy', age: 20 },
  { name: 'camperCat', age: 10 }
];
const names = users.map(user => user.name); // [ 'John', 'Amy', 'camperCat' ]

Checks:

/* indexOf() checks for the presence of an element -> takes element as parameter. Returns the position (index) or -1 if element does not exist */
let fruits = ['apples', 'pears', 'oranges', 'peaches', 'pears'];
fruits.indexOf('dates'); // returns -1
fruits.indexOf('oranges'); // returns 2
fruits.indexOf('pears'); // returns 1, the first index at which the element exists


/* every() checks if every element passes a particular test */
function checkPositive(arr) {
   return arr.every(num => num > 0); 
}
checkPositive([1, 2, 3, -4, 5]); // false


/* some() checks if any element passes a particular test. */
function checkPositive(arr) {
  return arr.some(num => num > 0); 
}
checkPositive([1, 2, 3, -4, 5]); // true

And there are several other build in methods like forEach(), filter(), etc.
https://www.w3schools.com/jsref/jsref_obj_array.asp

Note: As already mentioned, arrays are objects, therefore array functions are methods on the array object prototype, i.e. Array.prototype.push()

[SAPUI5] Copy Table Row

Button für das Kopieren einer Zeile hinzufügen.

<Table id="itemsTable" items="{oModel>/ITEMS}">
<columns>
      <Column id="splitColumn" hAlign="Center" demandPopin="false">
            <Text text="{i18n>SPLIT}"/>
      </Column>
</columns>
<items>
      <ColumnListItem>
            <cells>
                  <Button press="onSplitPressed" id="SPLIT_ROW" icon="{= ${oModel>CUSTOM_ITEM} === true ? 'sap-icon://delete' : 'sap-icon://add'}"/>
            </cells>
      </ColumnListItem>
</items>
</Table>

Nur neu hinzugefügte Zeilen sollen auch wieder gelöscht werden dürfen, daher werden manuell hinzugefügte Zeilen markiert mit CUSTOM_ITEM = True;
Via Expression Binding wird dann das erforderliche Icon bestimmt.

onSplitPressed: function (oEvent) {
		var oContext = oEvent.getSource().getBindingContext("oModel");
		var path = oContext.getPath();
		var oModel = oContext.getModel();
		var oItems = oModel.getProperty("/ITEMS");
		var index = path.substr(path.length - 1);

		//selektiertes Item lesen
		var oItem = oModel.getProperty(path);

		//was soll passieren? Zeile hinzufügen oder entfernen?
		if (oItem.CUSTOM_ITEM !== true) {

			//Neues Item anlegen
			var oNewItem = JSON.parse(JSON.stringify(oItem));
			//Markiere neue Zeile, da nur diese auch wieder gelöscht werden darf
			oNewItem.CUSTOM_ITEM = true;
			// +1 weil Zeile soll ja nach der Aktuellen einfügt werden
			index++; 
			oItems.splice(index, 0, oNewItem);

		} else {
			// Item löschen
			oItems.splice(index, 1);
		}

		oModel.setProperty("/ITEMS", oItems);
	},