I have has like this
var hash = {};
hash['a'] = ["a", "b", "c", "d", "e"];
hash['b'] = ["a", "b", "c"];
hash['k'] = ["q", "b"];
Math.max(Object.keys(hash)
.map(function(key) {
return hash[key].length;
})
)
It returns 5 but, I want to get the hash key 'a' at the same time.
Is it possible??
Combine Object.entries() and Array.prototype.reduce() to get the key and the elements behind that key (and their length)
var hash = {
a: ["a", "b", "c", "d", "e"]
,b: ["a", "b", "c"]
,k: ["q", "b"]
};
var result = Object.entries(hash)
.reduce((r, c) => r[1].length > c[1].length ? r : c);
console.log(result);
Does this fulfil your requirement?
I have used sort instead of Math.max here to find the maxima
var hash = {};
hash['a'] = ["a", "b", "c", "d", "e"];
hash['b'] = ["a", "b", "c"];
hash['k'] = ["q", "b"];
var result = Object.keys(hash)
.map(function(key) {
return {[key]: hash[key].length};
}).sort(function(a, b){
return a.key > b.key
})[0]
console.log(result);
i have used this approach for your problem:
var hash = {};
hash['a'] = ["a", "b", "c", "d", "e"];
hash['b'] = ["a", "b", "c"];
hash['k'] = ["q", "b"];
var largestInfo = {
key:'',
length:0
}
Object.keys(hash).map(function(key) {
if(hash[key].length > largestInfo.length){
largestInfo.key = key;
largestInfo.length = hash[key].length;
}
return hash[key].length;
});
console.log(largestInfo);
Related
I have 9 strings "a", "b", "c", "d", "e", "f", "g", "h", "i" in a JavaScript array.
const arr = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
I am printing the value of arr using JavaScript alert box.
but, if I use arr.join(" ") it is expected like:
a b c d e f g h i
but, I want to change the line for every 3rd element.
like:
a b c
d e f
g h i
How can I do this?
You can use a for loop with Array#slice.
const arr = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
const parts = [];
for(let i = 0; i < arr.length; i += 3){
parts.push(arr.slice(i, i + 3).join(' '));
}
console.log(parts.join('\n'));
This is what I use to chunk arrays:
const chunkSize = 3;
array
.map((_, i) =>
i % itemsPerPage
? undefined
: items.slice(
i,
Math.floor(i / chunkSize) * chunkSize + chunkSize
)
)
.filter(($) => !!$);
So chunk it up and use:
chunkedArray.map((array) => array.join(" ")).join("\n");
The .map used changes all the arrays inside to a b c and then join all of them with a newline character :)
You can also do that with join by using template literal. e.g:
var arr = ["P613221", "W123456", "ew76879", "GDG767"]
var stringWithQuotes = `'${arr.join(`', '`)}'`
console.log({
stringWithQuotes,
query: `SELECT * FROM users WHERE id IN (${stringWithQuotes})`
})
output:
"P613221', 'W123456', 'ew76879', 'GDG767"
Source Arrays:
var arr1 = ["a", "b"];
var arr2 = ["c"];
var arr3 = ["d", "e", "f"];
I can do permutations:(No duplicate)
["a", "c", "d"],
["b", "c", "d"],
["b", "c", "e"],
["b", "c", "f"],
["a", "c", "e"],
["a", "c", "f"]
But how can I get the results permutation like?
["a", "c"],
["a", "d"],
["a", "e"],
["a", "f"],
["b", "c"],
["b", "d"],
["b", "e"],
["b", "f"],
["c", "d"],
["c", "e"],
["c", "f"]
I only got my single array permutation snippet here
var arr3 = ['d', 'e', 'f'];
function permutation (list, n) {
var results = []
function _perm (list, n, res, start) {
if (res.length === n) {
return results.push(res.join(','))
}
if (start === list.length) { return }
_perm(list, n, res.slice(), start + 1)
res.push(list[start])
_perm(list, n, res, start + 1)
}
_perm(list, n, [], 0)
return results
}
console.log(permutation(arr3, 2)) // print ["e,f", "d,f", "d,e"]
Because of the source arrays could be unlimited, I need to combine and permute them at the same time.
I would like to know what is the best to achieve like this:
var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e', 'f'];
...
var arrN = ['x', 'y', 'z'];
permutation([arr1, arr2, arr3, arr4], 2)
permutation([arr1, arr2, arr3, arr4], 3)
permutation([arr1, arr2, arr3, arr4], 4)
I really appreciate any helps.
You are looking to get the subsets of length N from your selection of arrays, then create the cartesian product of each subset.
// returns power set of arr filtered by length
function powerset(arr, len, pref=[]) {
if (len == 0) return [pref];
if (len > arr.length) return [];
if (len == arr.length) return [pref.concat(arr)]; // premature optimisation
const next = arr.slice(1);
return powerset(next, len-1, [...pref, arr[0]]).concat(powerset(next, len, pref));
}
// returns cartesian product of the arrays in the argument
function cartesian(arg) {
var r = [], max = arg.length-1;
function helper(arr, i) {
for (var j=0, l=arg[i].length; j<l; j++) {
var a = arr.slice(0); // clone arr
a.push(arg[i][j]);
if (i==max)
r.push(a);
else
helper(a, i+1);
}
}
helper([], 0);
return r;
}
var arrays = [
['a', 'b'],
['c'],
['d', 'e', 'f'],
['x', 'y', 'z']
];
console.log(powerset(arrays, 2).flatMap(cartesian));
console.log(powerset(arrays, 3).flatMap(cartesian));
console.log(powerset(arrays, 4).flatMap(cartesian));
here is the code without eval
var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e', 'f'];
var arr4 = ['x', 'y', 'z'];
comb=[arr1,arr2,arr3,arr4]
conc=comb.flat()
resx=[]
function permut(){ // number of arrays
for(let i=0;i<conc.length;i++){
for(let j=i+1;j<conc.length;j++){
b=[conc[i],conc[j]]
comb.forEach(x=>{
if (x.includes(conc[i]) && !x.includes(conc[j])) resx.push(b)
})
}
}
}
permut()
console.log(resx)
let's assume that we have two arrays like these:
let s1 = ["A", "B", "C", "D", "B"] // Note: "B" has been occurred 2 times
let s2 = ["A", "B", "C", "D", "B", "A", "X", "Y"] // // Note: "B" has been occurred 2 times just like s1 but we have another occurrence for "A"
I want to create a new array (let s3) based on these two arrays with this rule that we'll remove the element(s) with occurrences more than the same element's occurrence in array s1
so the s3 array would be like this:
let s3 = ["A", "B", "C", "D", "B", "X", "Y"] // we just removed "A" cause it occurred more than "A" occurances in s1
Note that we want anything else ("X", "Y"). we just want to handle the extra occurrences.
so far I can find the index of repeated occurrences like this but I can't find a way to compare each occurrence to see if it is an extra one or not (complicated):
let s1 = ["A", "B", "C", "D", "B"]
let s2 = ["A", "B", "C", "D", "B", "A", "X", "Y"]
var s3 = [];
for (let i = 0; i < s2.length; i++) {
for (let j = 0; j < s1.length; j++) {
if (s2[i] === s1[j]) {
s3.push(i);
break;
}
}
}
console.log(s3)
My English is poor and I don't know if I could explain the issue or not!
Note: I can simply use s3 = [...new Set(s2)] to remove repeated elements but I want something else.
Since you want to keep everything originally in s1 but only add items from s2 if they aren't already in you can initially set s3 to s1. Then loop over s2 and if s1 does not have the value then push it into s3.
const s1 = ["A", "B", "C", "D", "B"];
const s2 = ["A", "B", "C", "D", "B", "A", "X", "Y"];
const s3 = [...s1];
s2.forEach(d => {
if (!s1.includes(d)) s3.push(d);
});
console.log(s3);
You can use Map and filter
First Map the array1 to [key, value] format
Iterate over second array, if it's found in Map and value is grater than zero return true else return false,
If it is not found return true
let s1 = ["A", "B", "C", "D", "B"]
let s2 = ["A", "B", "C", "D", "B", "A", "X", "Y"]
let map = new Map()
s1.forEach(v=>{
if(map.has(v)){
map.set(v,map.get(v)+1)
} else{
map.set(v,1)
}
})
let final = s2.filter(val=>{
if(map.has(val)){
if(map.get(val)){
map.set(val, map.get(val)-1)
return true
}
return false
}
return true
})
console.log(final)
You could count the values of the first set and return the values for a given count or if not known then all items.
var s1 = ["A", "B", "C", "D", "B"],
s2 = ["A", "B", "C", "D", "B", "A", "X", "Y"],
count = s1.reduce((m, v) => m.set(v, (m.get(v) || 0) + 1), new Map),
s3 = s2.filter(v => count.get(v) ? count.set(v, count.get(v) - 1) : !count.has(v));
console.log(...s3);
Suppose I have arrays parent and child. I want to check if a child exists inside a parent array. The ordering matters.
Example:
parent = ["x", "a", "b", "c", "d", "e", "f", "g"]
child = ["a", "b", "c"]
//returns true
Example:
When parent has a different order:
parent = ["x", "g", "b", "c", "d", "e", "f", "a"]
child = ["a", "b", "c"]
//It should return false
How would I achieve this in Javascript?
Edit: I have tried this How to check if an array contains another array? but it did not work for my case
You can run a loop for child and change the index accordingly. You can also use a match variable to detect change in the sequence.
RETURN TRUE
var parent = ["x", "a", "b", "c", "d", "e", "f", "g"]
var child = ["a", "b", "c"];
var initIndex = parent.indexOf(child[0]);
var match = true;
for(var i=1; i<child.length; i++){
var varIndex = parent.indexOf(child[i]);
if( varIndex === initIndex+1){
initIndex = varIndex;
continue;
}
match = false;
}
console.log(match);
RETURN FALSE
var parent = ["x", "g", "b", "c", "d", "e", "f", "a"]
var child = ["a", "b", "c"];
var initIndex = parent.indexOf(child[0]);
var match = true;
for(var i=1; i<child.length; i++){
var varIndex = parent.indexOf(child[i]);
if( varIndex === initIndex+1){
initIndex = varIndex;
continue;
}
match = false;
}
//return false
console.log(match);
USING STRING OPERATION
You can also convert the array to string to avoid those loop:
var parent = ["x", "g", "b", "c", "d", "e", "f", "a"]
var child = ["a", "b", "c"]
var parentStr = parent.toString();
var match = parentStr.indexOf(child.toString()) !== -1;
//return false
console.log(match);
parent = ["x", "a", "b", "c", "d", "e", "f", "g"]
child = ["a", "b", "c"]
parentStr = parent.toString();
match = parentStr.indexOf(child.toString()) !== -1;
//return true
console.log(match);
Convert the array to string by using JSON.stringify() and remove the square brackets from child string.
Now check the indexOf child in parent to check if it contains the child.
let parent = ["x", "a", "b", "c", "d", "e", "f", "g"];
let child = ["a", "b", "c"];
var parStr = JSON.stringify(parent);
var chldStr = JSON.stringify(child).replace('[', '').replace(']', '')
console.log(parStr.indexOf(chldStr) !== -1);
I wrote a function for this a while back that takes some paramenters:
Array.prototype.containsArray = function (child, orderSensitivity, caseSensitivity, typeSensitivity) {
var self = this;
if (orderSensitivity) return orderSensitiveComparer();
else return orderInsensitiveComparer();
function orderSensitiveComparer() {
var resultArry = [],
placeholder = 0;
if (child.length > self.length) return false;
for (var i = 0; i < child.length; i++) {
for (var k = placeholder; k < self.length; k++) {
if (equalityComparer(self[k], child[i])) {
resultArry.push(true);
if (resultArry.length === child.length) return true;
placeholder = k + 1;
break;
}
else resultArry = [];
}
}
return false;
}
function orderInsensitiveComparer() {
for (var i = 0; i < child.length; i++) {
var childHasParentElement = false;
for (var k = 0; k < self.length; k++) {
if (equalityComparer(child[i], self[k])) {
childHasParentElement = true;
break;
}
}
if (!childHasParentElement) return false;
}
return true;
}
function equalityComparer(a, b) {
if (caseSensitivity && typeSensitivity) return caseSensitiveEq(a, b) && typeSensitiveEq(a, b);
else if (!caseSensitivity && typeSensitivity) return caseInsensitiveEq(a, b) && typeSensitiveEq(a, b);
else if (caseSensitivity && !typeSensitivity) return caseSensitiveEq(a, b) && typeInsensitiveEq(a, b);
else if (!caseSensitivity && !typeSensitivity) return caseInsensitiveEq(a, b) && typeInsensitiveEq(a, b);
else throw "Unknown set of parameters";
function caseSensitiveEq(a, b) {
return a == b;
}
function caseInsensitiveEq(a, b) {
return (a + "").toLowerCase() == (b + "").toLowerCase();
}
function typeSensitiveEq(a, b) {
return typeof(a) === typeof(b);
}
function typeInsensitiveEq(a, b) {
return true;
}
}
}
var parent = [1, 2, 3, "a", "b", "c"];
var child = [1, 2, 3];
var child2 = ["1", "2", "3"];
var child3 = ["A", "b", "C"];
var child4 = ["a", "b", "c"];
var child5 = ["c", "b", "a"];
// Tests:
console.log(parent.containsArray(parent));
console.log(parent.containsArray(child));
console.log(parent.containsArray(child2));
// parent to child 2, order sensitive, not case, not type. => true.
console.log(parent.containsArray(child2, true, false, false));
// parent to child 2, order, not case, type. => false. b/c of type.
console.log(parent.containsArray(child2, true, false, true));
// parent to child 3, order, not case, type. => true.
console.log(parent.containsArray(child3, true, false, true));
// parent to child 4, order, case and type => true.
console.log(parent.containsArray(child4, true, true, true));
// parent to child 4, not order, case and type. => true.
console.log(parent.containsArray(child4, false, true, true));
// parent to child 5, not order case or type => true.
console.log(parent.containsArray(child5));
I have a simple method for small sized arrays of this problem.
First join the array to a string, see Array/join
Search substring, see String/indexOf
parent = ["x", "a", "b", "c", "d", "e", "f", "g"];
child = ["a", "b", "c"];
function matchSubArray(parent, child) {
parentStr = parent.join('');
childStr = child.join('');
return parentStr.indexOf(childStr) != -1;
}
matchSubArray(parent, child);
var parent = ["x", "g", "b", "c", "d", "e", "f", "a"]
var child = ["a", "b", "c"]
if(parent.join("").search(child.join("")) === -1) {
console.log("Not found");
} else {
console.log("found")
}
I am new to JavaScript here. I am trying to create a variable duplicated from a object property. When I make changes to the new variable, the original variable is also changed. How can I break the link between the two variables?
For instance,
var a = {};
a.data = ["a", "b", "c", "d"];
var b = a.data;
b.splice(0,1);
The output looks like the following.
> b
> ["b", "c", "d"]
> a.data
> ["b", "c", "d"]
What I expect is this.
> b
> ["b", "c", "d"]
> a.data
> ["a", "b", "c", "d"]
Clone the array :
var b = a.data.slice();