I have an Object containing multiple arrays like this
someObj = {
array1:['a', 'b'],
array2:['a', 'b', 'c'],
array3:['a', 'b', 'c', 'd']
}
Is there any built-in method or property in JS/ES6 which returns the largest array or length of the largest array? Please suggest
You can use Array.prototype.reduce and check the value of accumulator with the array length.
Use Object.values() to get all the values of the array.
var someObj = {
array1:['a', 'b'],
array2:['a', 'b', 'c'],
array3:['a', 'b', 'c', 'd'],
array4:['a', 'b', 'c']
}
var maxLength = Object.values(someObj).reduce((a,e) => { return a > e.length ? a:e.length}, 0);
console.log(maxLength);
You can use Object.values to get all of the values for any object. Here's a neat oneshot which will return the longest list in combination with reduce:
const longestList = Object.values(someObj)
.reduce((longest, list) => list.length > longest.length ? list : longest)
Object.values: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values
reduce: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
You can simply use a for loop and iterate through it comparing the length of the arrays.
var someObj = {
array1:['a', 'b'],
array2:['a', 'b', 'c'],
array3:['a', 'b', 'c', 'd']
}
var max=0;
for(x in someObj){
someObj[x].length > max ? max=someObj[x].length : max;
}
console.log(max);
Related
Consider the following arrays:
['a', 'b', 'a'] //method should return true
['a', 'b', 'c'] //method should return true
['a', 'c', 'c'] //method should return false
I want to write a method that most efficiently checks to see if both 'a' and 'b' exist in the array. I know I can do this in a simple for loop
let a_counter = 0;
let b_counter = 0;
for (let i = 0; i < array.length; i++) {
if (array[i] === 'a') {
a_counter++;
}
if (array[i] === 'b') {
b_counter++;
}
}
return (a_counter > 0 && b_counter > 0);
But this isn't very short. I can do indexOf but that will loop through twice. I have also considered using a set as below:
const letter_set = new Set(array)
return (letter_set.has('a') && letter_set.has('b'))
But I am pretty unfamiliar with sets and don't know if this solution could potentially be more expensive than just looping. I know that has() operations should be faster than array iterations but constructing the set probably takes at least O(N) time (I'm assuming).
Is there a clean and efficient way to find multiple elements in an array? ES6 answers welcome
You can use every and includes to do this check.
So we are saying every item must be included in the array.
function contains(arr, ...items) {
return items.every(i => arr.includes(i))
}
console.log(contains(['a', 'b', 'a'], 'a', 'b'))
console.log(contains(['a', 'c', 'c'], 'a', 'b'))
console.log(contains(['a', 'b', 'c'], 'a', 'b', 'c'))
console.log(contains(['a', 'b', 'c', 'd'], 'a', 'b', 'c', 'd', 'e'))
You could use just the Set and check if the wanted items are in the items array.
const
check = (items, wanted) => wanted.every(Set.prototype.has, new Set(items));
console.log(check(['a', 'b', 'a'], ['a', 'b'])); // true
console.log(check(['a', 'b', 'c'], ['a', 'b'])); // true
console.log(check(['a', 'c', 'c'], ['a', 'b'])); // false
array.includes('a') && array.includes('b')
includes seems like a real handy way to check for specific elements, even if there is more than one.
Not as compact as the other examples, but it does do the job in single run.
const arr1 = ['a', 'b', 'a']; //method should return true
const arr2 = ['a', 'c', 'c']; //method should return false
const arr3 = ['a', 'b', 'c']; //method should return true
const reducer = ({ a, b }, char) => ({
a: a || char === 'a',
b: b || char === 'b'
});
const includesAnB = arr => {
const { a, b } = arr.reduce(reducer, {});
return a && b;
}
console.log(includesAnB(arr1));
console.log(includesAnB(arr2));
console.log(includesAnB(arr3));
I have an array like:
A = ['a', 'del', 'b', 'del', 'c']
how can i remove the elements del such that the result is,
B = ['a', 'b', 'c']
I tried the pop and indexOf method but was unable
Use filter() for filtering elements from an array
var A = ['a', 'del', 'b', 'del', 'c'];
var B = A.filter(function(v) {
return v != 'del';
});
console.log(B);
For older browser check polyfill option of filter method.
In case if you want to remove element from existing array then use splice() with a for loop
var A = ['a', 'del', 'b', 'del', 'c'];
for (var i = 0; i < A.length; i++) {
if (A[i] == 'del') {
A.splice(i, 1); // remove the eleemnt from array
i--; // decrement i since one one eleemnt removed from the array
}
}
console.log(A);
This question already has answers here:
"Variable" variables in JavaScript
(9 answers)
Closed 8 years ago.
Working with the following code:
Array0 = ['a', 'b', 'c'];
Array1 = ['c', 'd', 'e'];
Array2 = ['x', 'a', 'd'];
...
/*
doStuff() is a recursive function whose argument is an abitrary length array
containing an arbitrary list of array names
e.g., anArr = ['Array1', 'Array0', 'Array1', 'Array2', ...]
*/
function doStuff(anArr) {
for(i=0; i<anArr.length; i++) {
switch(anArr[i]) {
case('Array0') : Array0.myMethod(); break;
case('Array1') : Array1.myMethod(); break;
case('Array2') : Array2.myMethod(); break;
}
}
}
Is there a way to replace the switch() block with a single statement:
<<array referenced by 'someArray'>>.aMethod() //or
function aFunction (<<array referenced by 'someArray'>>){}
Plain Javascript, please - no jquery or other library.
Thanks
Use an object in the first place.
var foo = {
Array0 : ['a', 'b', 'c'];
Array1 : ['c', 'd', 'e'];
Array2 : ['x', 'a', 'd'];
}
Then you can:
foo[anArr[i]].myMethod();
You can store the actual arrays in the array...
Array0 = ['a', 'b', 'c'];
Array1 = ['c', 'd', 'e'];
Array2 = ['x', 'a', 'd'];
var anArr = [Array0, Array1, Array2];
for(i=0; i<anArr.length; i++) {
anArr[i].myMethod();
}
The question doesn't make much sense but not sure how to word it without an example. If someone can word it better, feel free to edit it.
Let's say I have an array of arrays such as this:
[ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ]
I would like the output to be:
['a', 'a', 'b', 'b', 'b', 'c', 'd', 'e']
Not sure if there is an easy way to do this in javascript/jquery/underscore. One way I could think of is to look through each of these arrays and count up the number of times each element shows up and keep track of the maximum amount of times it shows up. Then I can recreate it. But that seems pretty slow considering that my arrays can be very large.
You need to:
Loop over each inner array and count the values
Store each value and its count (if higher than current count) in a counter variable
In the end, convert the value and counts into an array
Following code shows a rough outline of the process. Remember to replace .forEach and for..in with appropriate code:
var input = [['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e']],
inputCount = {};
input.forEach(function(inner) {
var innerCount = {};
inner.forEach(function(value) {
innerCount[value] = innerCount[value] ? innerCount[value] + 1 : 1;
});
var value;
for (value in innerCount) {
inputCount[value] = inputCount[value] ? Math.max(inputCount[value], innerCount[value]) : innerCount[value];
}
});
console.log(inputCount);
// Object {a: 2, b: 3, c: 1, d: 1, e: 1}
After messing around, I found a solution but not sure if I like it enough to use. I would probably use it if I can't think of another one.
I would use underscorejs countBy to get the count of all the elements.
var array = [ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ];
var count = _.map(array, function(inner) {
return _.countBy(inner, function(element) {
return element;
});
});
var total = {};
_.each(_.uniq(_.flatten(array)), function(element) {
var max = _.max(count, function(countedElement) {
return countedElement[element];
});
total[element] = max[element];
});
console.log(total); // {a: 2, b: 3, c: 1, d: 1, e: 1}
Then I would recreate the array with that total.
Here is example of simple nested loop approach:
var input = [ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ];
var countMap = {};
// iterate outer array
for (i=0; i < input.length; i++) {
// iterate inner array
for (j=0; j < input[i].length; j++) {
// increment map counter
var value = input[i][j];
if (countMap[input[i][j]] === undefined) {
countMap[value] = 1;
} else {
countMap[value]++;
}
}
}
console.log(countMap); // output such as {'a':2, 'b':4, 'c':1, 'd':1, 'e':1}
Not the most efficient solution but it should describe you the process:
var big = [ ['a', 'a', 'b', 'c'], [], ['d', 'a'], ['b', 'b', 'b', 'e'] ];
function map(arr){
var map = {}
for (var i=arr.length-1; i>-1; i--){
if(arr[i] in map) map[arr[i]]++;
else map[arr[i]] = 1;
}
return map;
}
function reduce(matrix){
var arrMap = {};
for (var i=matrix.length-1; i>-1; i--){
var arrRes = map(matrix[i]);
for (var key in arrRes){
if( !arrMap[key] || arrMap[key] < arrRes[key])
arrMap[key] = arrRes[key];
}
}
return arrMap;
}
function calc(matrix){
var res = [],
arrMap = reduce(matrix);
for (var key in arrMap){
while(arrMap[key] > 0 ){
res.push(key);
arrMap[key]--;
}
}
return res;
}
console.log(calc(big));
// Array [ "e", "b", "b", "b", "a", "a", "d", "c" ]
I've found a lot of posts that solve this problem:
Assuming we have:
array1 = ['A', 'B', 'C', 'D', 'E']; array2 = ['C', 'E'];
Is there a proven and fast solution to compare two arrays against each other, returning one array without the values appearing in both arrays (C and E here). Desired solution:
array3 = ['A', 'B', 'D']
But what if you have:
array1 = ['A', 'B', 'C', 'D', 'D', 'E']; array2 = ['D', 'E'];
and you're looking for the solution to be:
array3 = ['A', 'B', 'C', 'D'] // don't wipe out both D's
Here is some context:
You are trying to teach students about how sentences work. You give them a scrambled sentence:
ate -- cat -- mouse -- the -- the
They start typing an answer: The cat
You would like the prompt to now read:
ate -- mouse - the
At present, my code takes out both the's.
Here is what I've tried:
(zsentence is a copy of xsentence that will get manipulated by the code below, join()ed and put to screen)
for (i=0; i < answer_split.length; i++) {
for (j=0; j < xsentence.length; j++) {
(function(){
if (answer_split[i] == xsentence[j]) { zsentence.splice(j,1); return; }
})();
}
}
Just iterate over the array of elements you want to remove.
var array1 = ['A', 'B', 'C', 'D', 'D', 'E'];
var array2 = ['D', 'E'];
var index;
for (var i=0; i<array2.length; i++) {
index = array1.indexOf(array2[i]);
if (index > -1) {
array1.splice(index, 1);
}
}
It's O(array1.length * array2.length) but for reasonably small arrays and on modern hardware this shouldn't remotely cause an issue.
http://jsfiddle.net/mattball/puz7q/
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/splice
You can use Filter also.
Please review below example.
var item = [2,3,4,5];
var oldItems = [2,3,6,8,9];
oldItems = oldItems.filter(n=>!item.includes(n))
so this will return [6,8,9]
and if you want to get only matched items then you have to write below code.
oldItems = oldItems.filter(n=>item.includes(n))
This will return [2,3] only.