Array Set Length unequal to Sum of Array Distribution - node.js

I have a list of user ids like so: ["1111","5555","1111","8983",...]. I then compute the distribution of the frequency of the ids. But somehow adding the size of the distribution bins is smaller than the user set.
function histogram(List){
var d = {};
for(const x of List){
if (x in d){
d[x]+=1;
}
else{
d[x]=1;
}
}
return d
}
var featureuserids = f1_users.concat(f2_users,f3_users,f4_users)
var featureusers = [...new Set(featureuserids)];
const featurehist = histogram(Object.values(histogram(featureuserids)))
const n_featureusers = featureusers.length
Here is an example output.
Feature Users: 17379
Feature Hist: { '1': 16359, '2': 541, '3': 93, '4': 6 }
What is my mistake?

I have found the answer. One of my Lists (f1_users) had saved the ids as int, while the others were in string format. Therefore they were counted double in the set. After converting them all to string the issue was fixed.

Related

Define and sort array of array content in TypeScript and Node.js

Just took up TypeScript a couple of weeks ago without much knowledge in JavaScript.
I am trying to go through all the files in the specified directory and put each file name (string) and change time (number) into an array of array and sort by change time.
It looks like this: [['natalie.jpg', 143], ['mike.jpg', 20], ['john.jpg', 176], ['Jackie.jpg', 6]]
Problem 1: I do not know how to specify the inner array content, string and number. Type? Interface? Class? Tuple?
Problem 2: I do not know how to sort by change time in ascending order, so that the array changes to: [['Jackie.jpg', 6], ['mike.jpg', 20], ['natalie.jpg', 143], ['john.jpg', 176]]
import fs from 'fs'
const dirPath = '/home/me/Desktop/'
type imageFileDesc = [string, number] // tuple
const imageFileArray = [imageFileDesc] // ERROR HERE!
function readImageFiles (dirPath: string) {
try {
const dirObjectNames = fs.readdirSync(dirPath)
for (const dirObjectName of dirObjectNames) {
const dirObject = fs.lstatSync(dirPath + '/' + dirObjectName)
if (dirObject.isFile()) {
imageFileArray.push([dirObjectName, dirObject.ctimeMs]) // ERROR HERE!
}
}
imageFileArray.sort(function (a: number, b: number) {
return b[1] - a[1] // ERROR HERE! Can we do something like b.ctime - a.ctime?
})
} catch (error) {
console.error('Error in reading ' + dirPath)
}
}
readImageFiles(dirPath)
console.log(imageFileArray)
import * as fs from 'fs'
// Read files in folder
const files = fs.readdirSync( './files' )
// This will store the file name and their modification time
const imageFileArray: [ string, Date ][] = []
for ( const file of files ) {
// You can get a file's last modified time through fs.stat
const stats = fs.statSync( `./files/${file}` )
const modifiedTime = stats.mtime
// Push a tuple containing the filename and the last modified time
imageFileArray.push( [ file, modifiedTime ] )
}
// Sort from older to newer
const sorted = imageFileArray.sort( (a, b) => a[1].getTime() - b[1].getTime() )
console.log( sorted )
The modified time returns a Date object. If you want to sort from newer to older, just invert the operation in the sort function.

nodejs convert decimal to hex(00-00) and reverse?

So I want to send a hex value to a service. The problem is that the service want this hex value in a specific format, 00-00, and also reversed.
For Example, when I want to tell the Service I want tag '1000':
1000 dec is 3E8 in hex. easy.
Now the service wants the format 03-E8.
Also the service reads from right to left so the final value would be E8-03.
Another example, '3' would be 03-00.
Edit:
I forgott to say that I dont need it as string, but as Uint8Array. So I would create the final result with new Uint8Array([232, 3]). (Eaquals E8-03 = 1000)
So the question in general is: How can I get a [232,3] from an input of 1000 or [3, 0] from 3?
Is there a build in methode or a pakage that already can do this convertion?
There's probably a much simpler way, but here is a simple solution.
Edit: If you need at least two pairs, you can change the first argument of padStart.
function dec2hexUi8Arr (n) {
const hex = (n).toString(16);
const len = hex.length;
const padLen = len + (len % 2);
const hexPad = hex.padStart(Math.max(padLen, 4), '0');
const pairs = hexPad.match(/../g).reverse().map(p => parseInt(p, 16));
const ui8Arr = new Uint8Array(pairs);
return ui8Arr;
}
const vals = [
1000,
3,
65536
].map(dec2hexUi8Arr);
console.log (vals);
I don't know any tool or package. I would do something like this:
const a = 1000;
const a0 = a % 256;
const a1 = Math.floor(a / 256);
const arr = new Uint8Array([a0, a1]);
console.log(arr);
const arrStr = []
arr.forEach((elem) => {
const str = elem.toString(16).toUpperCase();
if (str.length === 2) {
arrStr.push(str);
} else {
arrStr.push('0' + str)
}
});
console.log(arrStr.reverse().join('-'));
Output:
Uint8Array(2) [ 232, 3 ]
03-E8

Getting file name with second largest number in it when the numbers are same

I was trying to get file name in which is second largest number and it always outputs the file with largest number. What am I doing wrong?
Example: I have 3 file names in which are stored numbers like: 6 or 6 or 1 and it always outputs first file name with number 6 in it. I need to output the file name with second number 6.
const getSecondFileName = (pathToFolder) => {
const files = fs.readdirSync(pathToFolder);
const content = files.map(f => +fs.readFileSync(`${pathToFolder}/${f}`, 'UTF-8'));
const arrayCopy = [...content];
const secondLargestNum = arrayCopy.sort()[arrayCopy.length - 2]
const secondFileWithLargestInteger = files[content.indexOf(secondLargestNum)];
return secondFileWithLargestInteger;
}
Thank you for every answer.
since indexOf returns the first occurrence and you're firstLargestNum and secondLargestNum are the same (wich is a special case), let's handle it apart
const getSecondFileName = (pathToFolder) => {
let secondFileWithLargestInteger;
const files = fs.readdirSync(pathToFolder);
const arrLength = files.length;
const content = files.map(f => +fs.readFileSync(`${pathToFolder}/${f}`, 'UTF-8'));
const arrayCopy = [...content];
const sortedArray = arrayCopy.sort(function(a, b){
return a - b;
});;
const firstLargestNum = sortedArray[arrLength- 1];
const secondLargestNum = sortedArray[arrLength- 2];
if (firstLargestNum === secondLargestNum) {
const indexofFirst = content.indexOf(secondLargestNum);
// const indexofFirst = content.indexOf(firstLargestNum); same
secondFileWithLargestInteger = files[content.indexOf(secondLargestNum, (indexofFirst + 1))]
} else {
secondFileWithLargestInteger = files[content.indexOf(secondLargestNum)];
}
return secondFileWithLargestInteger;
}
I'm using a different method than yours here to sort, because element in your files are string.
var numbers = ['1', '5', '12', '3', '7', '15', '9'];
// Sorting the numbers array simply using the sort method
numbers.sort(); // Sorts numbers array
alert(numbers); // Outputs: 1,12,15,3,5,7,9
Sort method sorts the array elements alphabetically

get all values from dictionary

I'm using linqjs in my website and I'm trying to get all values of a dictionary populated with toDictionary() library extension.
Here is my code:
var imagesDictionary = Enumerable.from(data)
.select(function (x) {
var images = Enumerable.from(x.ImagesSections)
.selectMany(function (y) {
return Enumerable.from(y.Images)
.select(function (z) {
return z.Thumb;
});
})
.toArray();
return { Title: x.Title, Images: images };
})
.toDictionary("$.Title", "$.Images");
var imagesToPreload = imagesDictionary.toEnumerable()
.selectMany("$.Value");
I would that imagesToPreload become an array of all images contained in the dictionary but I can't understand how to do that and this:
var imagesToPreload = imagesDictionary.toEnumerable()
.selectMany("$.Value");
seems the way than everyone used to obtain that.
Could someone help me?
Since it appears you're using the linqjs 3 beta version, the format of the entries have changed. The properties are in lowercase now.
var imagesDictionary = Enumerable.from(data)
.toDictionary("$.Title",
"Enumerable.from($.ImagesSections).selectMany('$.Images', '$$.Thumb').toArray()"
);
var imagesToPreload = imagesDictionary.toEnumerable()
.selectMany("$.value") // lowercase 'value'
.toArray();

Looping through a hash

In my code below, the fields length was always 0, and I'm pretty sure there are some key-value pairs in it.
var fields = Reflect.fields(_commandMap);
trace("mapping "+fields.length);
You can't access values in a array form in a Hash.
Here is a Hash
var a = new Hash();
a.set("hello", 0);
a.set("bonjour", 1);
a.set("ohai", 2);
Here is some way you can access values/keys :
for (value in a)
{
trace(value); //Will trace 0, 1, 2 (no assurance that it will be in that order)
}
for (key in a.keys())
{
trace(key); //Will trace hello, bonjour, ohai (no assurance that it will be in that order)
}
If you want to convert your Hash into an Array, use Lambda:
var valueArray = Lambda.array(a);
trace(valueArray[0]); //can be 0, 1 or 2
//since keys() returns an Iterator, not an Iterable, we cannot use Lambda here...
var keyArray = [];
for (key in a.keys()) keyArray.push(key);
trace(keyArray[0]); //can be hello, bonjour or ohai

Resources