how to pickup a random item from a Map Ecma6 object? - javascript

map = new Map([
[ 1, 'one' ],
[ 2, 'two' ],
[ 3, 'three' ],
]);
How can I retrieve a random item from map ?

function nth(x, iterable) {
for (const el of iterable)
if (x-- == 0)
return el;
throw new Error("not found");
}
console.log(nth(Math.floor(Math.random() * map.size), map.values())) // or keys or entries

You could get first the values of the map in an array and then take the length of the array as random factor and take the value at the random index.
var map = new Map([[1, 'one'], [2, 'two'], [3, 'three']]),
values = [...map.values()],
random = values[Math.floor(Math.random() * values.length)];
console.log(random);

Assuming the keys in the Map were sequential, you would get a random number between 1 and Map.length, then retrieve the value from the Map corresponding to that random number.
map = new Map([
[ 1, 'one' ],
[ 2, 'two' ],
[ 3, 'three' ],
]);
const rand = Math.floor(Math.random() * map.size) + 1;
const randomFromMap = map.get(rand);
console.log(randomFromMap);
If the keys were not sequential, or not integers, you would need to use Map.prototype.keys() to return the keys as an array and then retrieve the random element using a random element from the keys array. Something like:
const map = new Map([
[ 1, 'one' ],
[ 2, 'two' ],
[ 3, 'three' ],
]);
const rand = Math.floor(Math.random() * map.size);
const mapKeys = Array.from(map.keys());
console.log(map.get(mapKeys[rand]))

Create an array from the map and pick a random key. You can use Math.round(Math.random() * (array.length - 1)) to create a "dice" value for your array.
map = new Map([
[ 1, 'one' ],
[ 2, 'two' ],
[ 3, 'three' ],
]);
let array = Array.from(map);
let dice = Math.round(Math.random() * (array.length - 1))
let value = array[dice];
// value contains an array with key/value pair.
console.log(value);

Related

What is the best way to check multidimensional array in typescript or javascript to detect duplicate values?

I have two dimensional array like below:
array = [ [ 1, 1 ], [ 1, 2 ], [ 1, 1 ], [ 2, 3 ] ]
I want to compare value in array index to see if they have duplicate values. For example
array[0] = [1,1];
array[1] = [1,2];
array[2] = [1,1];
We can see that value at index 0 and 2 are same that is [1,1]. So, in that case I want to have true flag. What is the most efficient way to do it? or What are different ways to do it? Any kind of suggestion or help would be great with bit of explanation. Thanks in advance.
You can achieve it by convert the inner array elements into a string just for the comparison purpose.
Demo :
const arr = [[ 1, 1 ], [ 1, 2 ], [ 1, 1 ], [ 2, 3 ]];
const stringConversion = arr.map((item) => JSON.stringify(item))
const duplicateElements = stringConversion.filter((item, index) => stringConversion.indexOf(item) !== index)
console.log(duplicateElements.length ? true : false);
So, what I think you can do is:
Cycle every element of the multidimensional array.
Then check if the two element are the same by accessing the "row" with the index 0 and index 1
I think you can use different way to loop the array, this is what I tried:
// DECLARATIONS
array = [[ 1, 1 ], [ 1, 2 ], [ 1, 1 ], [ 2, 3 ]];
// LOOPING THE ARRAY
for (row of array)
{
// RETURN TO CONSOLE OR WHATEVER THE BOOLEAN VALUE
console.log(row[0] == row[1]);
}
String to convert array to a one-dimensional array of strings and some to check if any element is duplicated:
const arr = [[1, 1], [1, 2], [1, 1], [2, 3]];
const result = arr.map(String).some((v, i, a) => a.indexOf(v) !== i);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Reorder an array of values in an object in Javascript

I have the following object that I am trying to sort so that the labels are "High, mid, low" all of the time. The order I get them are not always the same so I wanted to add another layer of ordering to ensure that I get "high, mid, low"
Before:
status:{
label:['mid', 'high', 'low'],
data:[4, 3, 1]
}
After:
status:{
label:['high', 'mid', 'low'],
data:[3, 4, 1]
}
The easiest way to sort those two arrays "linked" is by temporarily combining them into one array:
const status = {
label: ['mid', 'high', 'low'],
data: [4, 3, 1]
};
// Combine the two arrays into an array of pairs
const pairs = status.label.map((label, index) => [label, status.data[index]]);
console.log('pairsBefore', pairs); // [ ['mid', 4 ], ['high', 3 ], ['low', 1 ]]
// Used for sorting
const ORDER = ['high', 'mid', 'low'];
// Sort the pairs
pairs.sort((a, b) => {
const [labelA, dataA] = a;
const [labelB, dataB] = b;
// Gives 0 for 'high', 1 for 'mid' and 2 for 'low'
const indexA = ORDER.indexOf(labelA);
const indexB = ORDER.indexOf(labelB);
// Substract for A and B, see how Array.prototype.sort works
return indexA - indexB;
});
console.log('pairsAfter', pairs); // [ ['high', 3 ], ['mid', 4 ], ['low', 1 ]]
// Split it back into two arrays
const statusSorted = {
label: pairs.map(pair => pair[0]),
data: pairs.map(pair => pair[1]),
};
console.log('statusSorted', statusSorted);
//{
// label: ['high', 'mid', 'low'],
// data: [3, 4, 1],
//}

How to get all index of an array to new array

I have an array of arrays that I am trying to map. But I am having an issue with my mapping because mapping all indexes not just the one I want it to be mapping. I figured I can work my way around this by creating a new array of only of the data I am trying to map.
How can I push all index 2 into a new array? I have not been able to find an example of what I am attempting to do.
I am expecting an outcome of a new array that equals [231, 431, 481]
Here is an example of my code:
const array = [ ["name", 1, 231], [ "name", 2, 431], ["name", 3, 481] ]
console.log(array)
let percentage = array.map(function (num, i) {
return 100 * ((num - array[i - 1]) / (array[i - 1]));
});
You can do this
const array = [ ["name", 1, 231], [ "name", 2, 431], ["name", 3, 481] ]
const arrayNew = array.map(x => x[2])
// arrayNew === [231, 431, 481]
Check the inline comments
const array = [
["name", 1, 231],
["name", 2, 431],
["name", 3, 481],
];
// If you know, there will be 3 elements in array
console.log(array.map(([, , last]) => last));
console.log(array.map(({ 2: last }) => last));
// For any size of sub array, get the last element in map
console.log(array.map((arr) => arr[arr.length - 1]));

Filter array of 3-item arrays by third item; get result set without third items [duplicate]

This question already has answers here:
Filter Array of Array for values inside nested array
(4 answers)
Only specific 'columns' from a 2d javascript array
(4 answers)
Closed 4 months ago.
I have these variables:
var arr = [
[ "name1", 2, "filter1" ],
[ "name2", 5, "filter2" ],
[ "name3", 8, "filter3" ],
[ "name4", 1, "filter2" ]
];
// This variable may have values: `"filter1"`, `"filter2"`, `"filter3"`.
var filter = "filter2";
How can I filter the array arr according to the filter variable values?
My example must return this:
[
[ "name2", 5 ],
[ "name4", 1 ]
]
Beside the filtering, you need to get only the first two elements of the inner arrays.
Array#filter returns the same elements in the array. For getting the wanted items without the filter item, you need to return either the first two objects, or filter the items with the given filter as well (proposal 2).
var array = [['name1', 2, 'filter1'], ['name2', 5, 'filter2'], ['name3', 8, 'filter3'], ['name4', 1, 'filter2']],
filter = 'filter2',
result = array.filter(a => a[2] === filter).map(a => a.slice(0, 2));
console.log(result);
var array = [['name1', 2, 'filter1'], ['name2', 5, 'filter2'], ['name3', 8, 'filter3'], ['name4', 1, 'filter2']],
filter = 'filter2',
result = array
.filter(a => a.some(v => v === filter))
.map(a => a.filter(v => v !== filter));
console.log(result);
By using filter method you can easily test what you want and only return the match elements
var arr = [['name1', 2, 'filter1'], ['name2', 5, 'filter2'],['name3', 8, 'filter3'], ['name4', 1, 'filter2']];
var filter = 'filter2';
var result = arr.filter(function(res){
return res[2] == filter;
}).map(function(filtered){
return filtered.slice(0,2);
});
console.log(result);

Cartesian product without duplicates

I am using a cartesian product function that given [1], [1,2,3], [1,2,3] returns 9 combinations:
[ [ 1, 1, 1 ],
[ 1, 2, 1 ],
[ 1, 3, 1 ],
[ 1, 1, 2 ],
[ 1, 2, 2 ],
[ 1, 3, 2 ],
[ 1, 1, 3 ],
[ 1, 2, 3 ],
[ 1, 3, 3 ] ]
But I need to remove those with the same items regardless of the order, so [ 1, 3, 1 ] and [ 1, 1, 3 ] are the same to me. The result should contain 6 items:
[ [ 1, 1, 1 ],
[ 1, 2, 1 ],
[ 1, 3, 1 ],
[ 1, 2, 2 ],
[ 1, 3, 2 ],
[ 1, 3, 3 ] ]
I can write a function that compares all possible pairs with _.xor, but for larger numbers it will probably be very inefficient. Is there a good way in Javascript to do this? An efficient way to compare all possible pairs or an algorithm for cartesian product without duplicates?
sort each array of the cartesian product
[ 1, 2, 1 ] -> [1 , 1 , 2]
[ 1, 1, 2 ] -> [1 , 1 , 2]
then gather these sorted arrays into a set, that will remove the duplicates.
Of course, you can do that while constructing the cartesian product rather than afterward.
JavaScript has Set and Map, however they compare objects and arrays by reference rather than by value, so you cannot take advantage of it directly. The idea is to use a key function which sorts and json encodes the items before putting it in a set.
pure ES5:
function product(sets) {
if (sets.length > 0) {
var head = sets[0];
var tail = product(sets.slice(1));
var result = [];
head.forEach(function(x) {
tail.forEach(function(xs) {
var item = xs.slice(0);
item.unshift(x);
result.push(item);
});
});
return result;
} else {
return [[]];
}
}
function myKeyFn(item) {
return JSON.stringify(item.slice(0).sort());
}
function uniqBy(items, keyFn) {
var hasOwn = Object.prototype.hasOwnProperty, keyset = {};
return items.filter(function(item) {
var key = keyFn(item);
if (hasOwn.call(keyset, key)) {
return false;
} else {
keyset[key] = 1;
return true;
}
});
}
function uniqProduct(sets) {
return uniqBy(product(sets), myKeyFn);
}
function log(x) {
console.log(x);
var pre = document.createElement('pre');
pre.appendChild(document.createTextNode(x));
document.body.appendChild(pre);
}
log(uniqProduct([[1],[1,2,3],[1,2,3]]).map(JSON.stringify).join("\n"));
<pre></pre>
lodash + modern JavaScript:
// Note: This doesn't compile on current babel.io/repl due to a bug
function product(sets) {
if (sets.length > 0) {
const [x, ...xs] = sets;
const products = product(xs);
return _.flatMap(x, head => products.map(tail => [head, ...tail]));
} else {
return [[]];
}
}
function uniqProduct(sets) {
return _.uniqBy(product(sets), x => JSON.stringify(x.slice(0).sort()));
}
console.log(uniqProduct([[1],[1,2,3],[1,2,3]]).map(JSON.stringify).join("\n"));
JavaScript has set data structure.
So store your results in a set where each element of the set is a collection of pairs of numbers from the original sets along with the number of times that number occurs.
So your result would look something like this:
[
{1:3},
{1:2, 2: 1},
{ 1:2, 3:1},
{ 1:1, 2:2},
{ 1:1, 2:1, 3:1},
{ 1:1, 3:2 } ]
This way, you won't be able to add the object a second time to the set.

Categories

Resources