From f30e56fc48544cbf7f3173c9b969045fbc40fd82 Mon Sep 17 00:00:00 2001 From: mmasoud1 Date: Sat, 13 Jan 2024 16:33:33 -0500 Subject: [PATCH] Add tfjs functions --- js/histojs/designFunctionsv4.js | 88 ++++++++++++++++------- test/histojs_test/designFunctions_test.js | 51 +++++++++++++ 2 files changed, 113 insertions(+), 26 deletions(-) diff --git a/js/histojs/designFunctionsv4.js b/js/histojs/designFunctionsv4.js index fdfbc57..3b2492c 100644 --- a/js/histojs/designFunctionsv4.js +++ b/js/histojs/designFunctionsv4.js @@ -72,35 +72,47 @@ * @since 1.0.0 * @version 1.0.0 * @category Array - * @param {Array} array The array to process. + * @param {Array} arr - The array to process. * @param {*} element The value to inspect and remove. * @returns {Array} * @example * * removeArrayElem(['a', 'b', 'c', 'd'], 'c') * => ['a', 'b', 'd'] + *---------------------------------------------* + * await removeArrayElemTFJS( [1, 2, 3, 4], 3) + * => [1, 2, 4] * - * await removeArrayElemTFJS([1, 2, 3, 4], 3) + * await removeArrayElemTFJS(['a', 'b', 'c', 'd'], 'c') + * => ['a', 'b', 'd'] + *---------------------------------------------* + * await removeArrayElemTFJSV2( [1, 2, 3, 4], 3) * => [1, 2, 4] - * NOTE: TFJS version for numbers only + * NOTE: removeArrayElemTFJSV2 for numbers only + * */ - removeArrayElem = (array, element) => { - const index = array.indexOf(element); + removeArrayElem = (arr, element) => { + const index = arr.indexOf(element); if(index >= 0 ) { - array.splice(index, 1); + arr.splice(index, 1); } } - removeArrayElemTFJS = async (array, element) => { - const tensor = tf.tensor(array); + removeArrayElemTFJS = async(arr, element) => { + return await tf.data.array(arr).filter(elm => elm !== element).toArray(); + } + + + removeArrayElemTFJSV2 = async (arr, element) => { + const tensor = tf.tensor(arr); const mask = tf.notEqual(tensor, element); const result = await tf.booleanMaskAsync(tensor, mask); return result.arraySync(); } - removeArrayElem_v2 = (array, element) => { - return array.filter(elm => elm !== element); + removeArrayElem_v2 = (arr, element) => { + return arr.filter(elm => elm !== element); } @@ -258,6 +270,13 @@ * {id:"spx-7", Type:"Immune"} ]) * * => Object { "spx-1": {id: "spx-1", Type: "Tumor"}, "spx-7": {id: "spx-7", Type: "Immune"} } + * + * + * await array2ObjWithHashKeyTFJS( "id", [ {id:"spx-1", Type:"Tumor"}, + * {id:"spx-7", Type:"Immune"} ]) + * + * => Object { "spx-1": {id: "spx-1", Type: "Tumor"}, "spx-7": {id: "spx-7", Type: "Immune"} } + * */ array2ObjWithHashKey = (hashKey, arrayOfObjs) => { @@ -269,13 +288,32 @@ convertedObject[ object[hashKey] ] = object; }); - return convertedObject; + return convertedObject; + } else { triggerHint("Not a valid array of objects .. ") return null; } } + array2ObjWithHashKeyTFJS = async(hashKey, arrayOfObjs) => { + if(Object.keys(arrayOfObjs).length) { + // create hash folarger arrayr the + let convertedObject = {}; + + await tf.data.array(arrayOfObjs).forEachAsync(object => { + convertedObject[ object[hashKey] ] = object; + }); + + return convertedObject; + + } else { + triggerHint("Not a valid array of objects .. ") + return null; + } + } + + /** * Find unique values of array and return as new array. This is helpful for heatmapColor scale function @@ -336,27 +374,27 @@ * * => [{ Type: "1", val: 1}, { Type: "2", val: 2}, { Type: "3", val: 3}, { Type: "4", val: 4}] ********************************************************************************************* - * fastArraysConcatTFJS( [1, 1, 2, 3], [5, 2, 5]) + * fastArraysConcatTFJSV2( [1, 1, 2, 3], [5, 2, 5]) * * => [1, 1, 2, 3, 5, 2, 5] * - * NOTE: fastArraysConcatTFJS can not concate Array of objects. + * NOTE: fastArraysConcatTFJSV2 can not concate Array of objects. * - * fastArraysConcatTFJS( array1, array2) + * fastArraysConcatTFJSV2( array1, array2) * * => [ NaN, NaN, NaN, NaN ] ********************************************************************************************** - * NOTE: fastArraysConcatTFJSData returns promise + * NOTE: fastArraysConcatTFJS returns promise * - * await fastArraysConcatTFJSData( [1, 1, 2, 3], [5, 2, 5]) + * await fastArraysConcatTFJS( [1, 1, 2, 3], [5, 2, 5]) * OR - * fastArraysConcatTFJSData([1, 1, 2, 3], [5, 2, 5]).then(function(res) { console.log(res) }) + * fastArraysConcatTFJS([1, 1, 2, 3], [5, 2, 5]).then(function(res) { console.log(res) }) * * => [1, 1, 2, 3, 5, 2, 5] * - * await fastArraysConcatTFJSData( array1, array2) + * await fastArraysConcatTFJS( array1, array2) * OR - * fastArraysConcatTFJSData(array1,array2).then(function(res) { console.log(res) }) + * fastArraysConcatTFJS(array1,array2).then(function(res) { console.log(res) }) * * => [{ Type: "1", val: 1}, { Type: "2", val: 2}, { Type: "3", val: 3}, { Type: "4", val: 4}] */ @@ -366,18 +404,16 @@ } fastArraysConcatTFJS = (array1, array2) => { - const tensor1 = tf.tensor1d(array1); - const tensor2 = tf.tensor1d(array2); - return tf.concat([tensor1, tensor2]).arraySync(); - } - - - fastArraysConcatTFJSData = (array1, array2) => { const dataArr1 = tf.data.array(array1); const dataArr2 = tf.data.array(array2); return dataArr1.concatenate(dataArr2).toArray(); } + fastArraysConcatTFJSV2 = (array1, array2) => { + const tensor1 = tf.tensor1d(array1); + const tensor2 = tf.tensor1d(array2); + return tf.concat([tensor1, tensor2]).arraySync(); + } /** * Find if two arrays are identical. diff --git a/test/histojs_test/designFunctions_test.js b/test/histojs_test/designFunctions_test.js index fe1f897..ed98511 100644 --- a/test/histojs_test/designFunctions_test.js +++ b/test/histojs_test/designFunctions_test.js @@ -25,6 +25,14 @@ describe("Main Design Phase Functions", function () { }); }); + describe('#findObjectByKeyValueTFJS()', function () { + it('return array element', function () { + return findObjectByKeyValueTFJS( [{id: "1", value: "val1"}, {id: "2", value: "val2"}] , 'id', "2").then(result => { + expect( result ).to.eql({id: "2", value: "val2"}); + }); + }); + }); + describe('#removeArrayElem()', function () { it('return array after remove element', function () { let arr2Test = ['a', 'b', 'c', 'd']; @@ -33,6 +41,14 @@ describe("Main Design Phase Functions", function () { }); }); + describe('#removeArrayElemTFJS()', function () { + it('return array after remove element', function () { + return removeArrayElemTFJS(['a', 'b', 'c', 'd'], 'c').then(result => { + expect( result ).to.eql(['a', 'b', 'd']); + }); + }); + }); + describe('#insertArrayElem()', function () { it('return array after insert an element', function () { let arr2Test = ['b', 'c', 'd']; @@ -61,6 +77,18 @@ describe("Main Design Phase Functions", function () { }); }); + describe('#mergeArrayOfObjByKeyTFJS()', function () { + it('return merged two arrays of objects by common key ', function () { + return mergeArrayOfObjByKeyTFJS( "id", [ {id:"spx-1", Type:"Tumor"}, + {id:"spx-7", Type:"Immune"} ], + [{id : "spx-1", area: 250, solidity: 0.95}, + {id : "spx-3", area: 150, solidity: 0.85}, + {id : "spx-7", area: 100, solidity: 0.80} ]).then(result => { + expect( result ).to.be.an('array'); + }); + }); + }); + describe('#array2ObjWithHashKey()', function () { it('return a conversion of array of objects to object with hashing key', function () { expect(array2ObjWithHashKey( "id", [ {id:"spx-1", Type:"Tumor"}, @@ -69,18 +97,41 @@ describe("Main Design Phase Functions", function () { }); }); + describe('#array2ObjWithHashKeyTFJS()', function () { + it('return a conversion of array of objects to object with hashing key', function () { + return array2ObjWithHashKeyTFJS( "id", [ {id:"spx-1", Type:"Tumor"}, + {id:"spx-7", Type:"Immune"} ]).then(result => { + expect( result ).to.eql({ "spx-1": {id: "spx-1", Type: "Tumor"}, "spx-7": {id: "spx-7", Type: "Immune"} }); + }); + }); + }); + describe('#arrayUniqueValues()', function () { it('return unique values of array ', function () { expect( arrayUniqueValues( [1, 1, 2, 3, 2, 5]) ).to.eql([1, 2, 3, 5]); }); }); + describe('#arrayUniqueValuesTFJS()', function () { + it('return unique values of array ', function () { + expect( arrayUniqueValuesTFJS( [1, 1, 2, 3, 2, 5] ) ).to.eql([1, 2, 3, 5]); + }); + }); + describe('#fastArraysConcat()', function () { it('return fast arrays concatenation ', function () { expect( fastArraysConcat( [1, 1, 2, 3], [5, 2, 5]) ).to.eql([1, 1, 2, 3, 5, 2, 5]); }); }); + describe('#fastArraysConcatTFJS()', function () { + it('return fast arrays concatenation ', function () { + return fastArraysConcatTFJS( [1, 1, 2, 3], [5, 2, 5]).then(result => { + expect( result ).to.eql([1, 1, 2, 3, 5, 2, 5]); + }); + }); + }); + describe('#areArraysEquals()', function () { it('return if two arrays are identical ', function () { expect( areArraysEquals( [1, 1, 2, 3], [1, 1, 2, 5]) ).to.be.false