Test for equality of arrays - javascript

How in the test to compare each value of the array, and not the entire array?
In my test, I compared the standardArray, but I need to compare List [1,2,3,4], but I'll get it so that the test does not lose its meaning.
Maybe somehow by the indexes or otherwise ...
import { List, Set } from "immutable"
let standardArray = List([1,2,3,4]);
export function mass(standardArray) {
let mutatedArray = standardArray.map(x => x * 2);
return mutatedArray;
};
test code:
import { List, Set, isImmutable, Record, Map } from "immutable"
import { mass } from "./sum";
test('aligning arrays', () => {
let standardArray = List([1,2,3,4]);
for (let i = 0; i < 1; i++) {
expect(mass(standardArray)).toEqual(standardArray.map(x => x * 2));
};
});

If you want to check each value you can try something like this:
test('values should match', () => {
let originalArray = List([1,2,3,4]);
let expectedResult = List([2,4,6,8]);
let actuaResult = mass(originalArray);
for (let i = 0; i < originalArray.length; i++) {
expect(expectedResult[i]).toEqual(actuaResult[i]);
};
});

Related

Javascript split strings in array on specific index

I have this array of strings.
const numbersArray = ['1000','10000','100000']
My goal is to split each one of them on specific index for example: output of 1000 should be 1,000 and etc...
Here is what i have right now:
const splitArrayHandler = (arr) =>{
for (let i = 0; i < arr.length; i++) {
let indexOfSymbol = Math.round(arr[i].length / 3)
return splitAtIndex(arr[i],indexOfSymbol)
}
}
const splitAtIndex = (value,index) => {
return value.substring(0,index) + ',' + value.substring(index)
}
splitArrayHandler(numbersArray)
The first function splitArrayHandler loops through my array,finds specific index of the symbol in the string and then function splitAtIndex does the rest of the hard work.
The problem is only first element of the string is passing to the splitAtIndexfunction and I dont understand why. any suggestions please?
const numbersArray = ['1000','10000','100000']
const splitArrayHandler = (arr) =>{
for (let i = 0; i < arr.length; i++) {
let indexOfSymbol = Math.round(arr[i].length / 3)
return splitAtIndex(arr[i],indexOfSymbol)
}
}
const splitAtIndex = (value,index) => {
return value.substring(0,index) + ',' + value.substring(index)
}
splitArrayHandler(numbersArray)
Use Intl.NumberFormat for the job. No need for string parsing / manipulating:
const numbersArray = ['1000', '10000', '100000', '654654686156', '1000.66', '10e14', '0xFFFF'];
const format = new Intl.NumberFormat('en-US').format;
const formattedNumbers = numbersArray.map(Number).map(format);
console.log(formattedNumbers);
You are breaking the loop by returning the splitAtIndex function. Create another array and push the results to it.
const splitArrayHandler = (arr) =>{
let arr2 = []
for (let i = 0; i < arr.length; i++) {
let indexOfSymbol = Math.round(arr[i].length / 3)
arr2.push(splitAtIndex(arr[i],indexOfSymbol))
}
return arr2
}
You might use regular expression and map function (though there is no real difference between map and hard coded loop)
const numbersArray = ['1000','10000','100000']
function addComa(x) {
return x.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
const resolved = numbersArray.map(addComma)
console.log(resolved) // ['1,000','10,000','100,000']

How to extract the month values from the res.body.results array of objects using JS Array map()

Also trying to get that custom code that extracts the months from the string with regex in my code snippet. I believe I am close but not quite. Console log is returning "undefined" values for the key/value pairs and 0 for the months when it should return 60. Any thoughts on how to restructure this would be very much appreciated! I am trying to get the highest number of months/years from an array and set it to a property in HubSpot. Thank you kindly for any advice on how to properly configure to get correct values.
hubspotClient.crm.lineItems.batchApi.read({
inputs,
properties: ['hs_recurring_billing_period', 'recurringbillingfrequency',]
})
.then(res => {
const inputs = res.body.results.map(result => {
result.properties.recurringbillingfrequency =
result.properties.recurringbillingfrequency;
result.properties.months = Number(result.properties.months);
return { term: hs_recurring_billing_period, frequency: recurringbillingfrequency };
})
console.log(inputs);
let term = 0;
const largestNum = (years) => {
//let term = 0;
for (let i=0; i <res.body.results.length; i++){
let { recurringbillingfrequency, hs_recurring_billing_period } =
res.body.results[i].properties;
console.log(recurringbillingfrequency, hs_recurring_billing_period)
if(recurringbillingfrequency = "Annually")
{
let months = Number(hs_recurring_billing_period.replace(/\D/g, ''));
let years = months / 12;
// let term = 0;
if (years[i] > term) {
term = years[i];
}
}
}
return term;
}
console.log(largestNum(term));
return;
The map function looks strange to me:
const inputs = res.body.results.map(result => {
result.properties.recurringbillingfrequency = result.properties.recurringbillingfrequency;
result.properties.months = Number(result.properties.months);
return { term: hs_recurring_billing_period, frequency: recurringbillingfrequency };
})
within the scope of the mapping function, recurringbillingfrequency and hs_recurring_billing_period in the return object are not defined. Would it work by replacing the return value with as so?
return {
hs_recurring_billing_period: result.properties.hs_recurring_billing_period,
recurringbillingfrequency: result.properties.recurringbillingfrequency
};
Also, I am not quite sure how this line is necessary:
result.properties.recurringbillingfrequency = result.properties.recurringbillingfrequency;
So either this loop will work and extract the months and set to years or you can use Lodash with one line of code.
let term = 0;
for (let i=0; i <inputs.length; i++){
let { recurringbillingfrequency, hs_recurring_billing_period } =
inputs[i];
console.log(recurringbillingfrequency, hs_recurring_billing_period)
if(recurringbillingfrequency.toLowerCase() === 'annually')
{
let months = hs_recurring_billing_period;
let years = months / 12.0;
/*
let highest = 0;
function getHighestTerm(values) {
for (let j=0; j < values.length; j++)
if (j === 0) {
highest = values;
} else if (highest > values[j]) {
highest = values[j];
}
return highest;
}
*/
term = _.max(_.map(inputs, 'hs_recurring_billing_period')) / 12.0;

Array/Object Sorting

So there's a JSON Object, it has a list of arrays with objects in it, like AssortmentID and AssortmentParentID with a Name, AssortimentID's with an AssortmentParentID of 000-000-000 are folders, the AssortmentID's with the AssortmentParentID of another AssortmentID are the children of that folder.
How do I output the folders first, and then the children in each folder(parent).
Example:
The HTTP Request:
const url = "\url";
async function getAssortList() {
const response = await fetch(url);
const data = response.json();
const { Assortments } = data;
for (let i = 0; i < Assortments.length; i++) {
const assortItem = Assortments[i];
...(where I'm stuck)...
/////////////////////////////////////
The JSON Response:
Assortments: [
{
"AssortmentID": 123-123-123-123,
"AssortmentParentID": 000-000-000
"Name": "I am a parent"
},
{
"AssortmentID": 111-111-111-111,
"AssortmentParentID": 123-123-123-123,
"Name": "I am a kid"
}
Maybe this will help you.
Assortments.reduce((acc, curr) => {
let parent = curr["AssortmentParentID"];
if(acc[parent]){
acc[parent].push(curr)
}
else{
acc[parent] = [curr]
}
return acc;
}, {})
try below code in javascript
Assortments.sort(
function (a, b) {
var x = a.AssortmentParentID.toLowerCase();
var y = b.AssortmentParentID.toLowerCase();
if (x < y) {return -1;}
if (x > y) {return 1;}
return 0;
})
by this you will have sorted array on AssortmentParentID
Kind of, solved it myself. Still have things to do.
const parents = []; // created a new array that I'll push objects into later.
for (let i = 0; i < Assortments.length; i++) {
if (Assortments[i].AssortimentParentID == "000-000-000") {
parents.push(Assortments[i]);
}
}
for (let i = 0; i < parents.length; i++) {
parents.sort((a, b) => a.Name.localeCompare(b.Name)); // sort them alphabetically
}
If someone can show me how to do the same thing, using filter/find/etc., it would be great. Thank you!
UPDATE:
Managed to sort the parents, output them in DOM, here's the code:
for (let x in parents) {
parents[x].isFolder === false ? parents.push( parents.splice(x,1)[0] ) : 0;
}
let assortItem = parents[i].Name;
let subnavList = document.createElement("li");
let subnavLink = document.createElement("a");
subnavList.classList.add("subnav-list");
subnavList.appendChild(subnavLink);
subnavLink.classList.add("subnav-link");
subnavLink.innerHTML += assortItem;
item.appendChild(subnavList);

Weird Behavior Pushing Into Array Stored in a JavaScript Object's Value

Inside of the else clause, the commented out line gives the desired result, but the one below it causes { '1': [ 1.3 ], '2': [ 2.1 ] } to become { '1': [ 1.3 ], '2': 2 }. I don't understand why this is happening.
const groupBy = (array, callback) => {
let obj = {}
for (let i = 0; i < array.length; i++) {
let currKey = callback(array[i])
let newVal = array[i]
let currVal = obj[currKey]
if (!currVal) {
obj[currKey] = [newVal]
} else {
// obj[currKey].push(newVal)
obj[currKey] = currVal.push(newVal)
}
}
return obj
}
// Uncomment these to check your work!
var decimals = [1.3, 2.1, 2.4]
var floored = function(num) { return Math.floor(num) }
groupBy(decimals, floored); // expect { 1: [1.3], 2: [2.1, 2.4] }
Array.prototype.push does not return a new array, it returns the length of the array.
const groupBy = (array, callback) => {
// let arrayValues = [] // this isn't used anywhere
let obj = {}
for (let i = 0; i < array.length; i++) {
let currKey = callback(array[i])
let newVal = array[i]
let currVal = obj[currKey]
if (!currVal) {
obj[currKey] = [newVal]
} else {
obj[currKey].push(newVal) // this should work instead
//obj[currKey] = currVal.push(newVal)
}
}
return obj
}
Since arrays are a reference type you just need to push your new item into the array obj[currKey].push(newValue) without setting obj[currKey] again. You're pushing a new value into that array where it lives in memory so no need to re-assign it to anything. You can see how lodash does that here (although you'll have to untangle some helper functions).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

verification of the equality of immutable arrays

I have two immutable arrays. One is ordinary ([1,2,3,4]), the other is multiplied by two ([2,4,6,8]).
How in the test to equalize each value of the first array with the value of the second I use the iteration? That 1 is 2, and 2 is 4 and so on.
I think this can be done with a for loop, but I do not know how to write this in practice.
import { List, Set } from "immutable"
export function mass() {
let standardArray = List([1,2,3,4]);
let mutatedArray = standardArray.map(x => x * 2);
return mutatedArray;
};
test code
(I do not know how to proceed)
import { List, Set, isImmutable, Record, Map } from "immutable"
import { mass } from "./sum";
test('Array Multiplication Test', () => {
let standardArray = List([1,2,3,4]);
let mutatedArray = standardArray.map(x => x * 2);
expect(standardArray).not.toEqual(mutatedArray);
});
Why not make use of a flag. Take a flag variable and set it to any value, loop through the array and if any value does not meet expectations, change the flag variable.
In the end, check the value of flag variable. If it is the same as set initially then they are same otherwise the arrays are different.
import { List, Set, isImmutable, Record, Map } from "immutable"
import { mass } from "./sum";
test('Array Multiplication Test', () => {
let standardArray = List([1,2,3,4]);
let mutatedArray = standardArray.map(x => x * 2);
let flag = false;
for (let i = 0; i < standardArray.length; i++) {
if (standardArray[i] * 2 != mutatedArray[i]) {
flag = true;
break;
}
}
expect(flag).toEqual(false);
});
I think you want something like this:
let testArr1 = [1,2,3,4]
let testArr2 = [2,4,6,8]
let testArr3 = [2,6,6,8]
function doesMatchCriteria(arr1, arr2) {
if (arr1.length !== arr2.length) return false;
return arr1.every((e, i) => ((e*2) === arr2[i]));
return true;
}
console.log(doesMatchCriteria(testArr1, testArr2)); // true
console.log(doesMatchCriteria(testArr1, testArr3)); // false
So, your test function could be something like this:
test('Array Multiplication Test', () => {
let testArr1 = [1,2,3,4]
let testArr2 = [2,4,6,8]
expect(doesMatchCriteria(testArr1, testArr2)).toBe(true);
});
Don't forget to define doesMatchCriteria function in the same file.

Categories

Resources