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 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);
What I am doing wrong here? I am getting TypeError: items[i] is undefined as the error.
var items = [];
for(var i = 1; i <= 3; i++){
items[i].push('a', 'b', 'c');
}
console.log(items);
I need an output as given below,
[
['a', 'b', 'c'],
['a', 'b', 'c'],
['a', 'b', 'c']
]
You could simply use the following:
items.push(['a', 'b', 'c']);
No need to access the array using the index, just push another array in.
The .push() method will automatically add it to the end of the array.
var items = [];
for(var i = 1; i <= 3; i++){
items.push(['a', 'b', 'c']);
}
console.log(items);
As a side note, it's worth pointing out that the following would have worked:
var items = [];
for(var i = 1; i <= 3; i++){
items[i] = []; // Define the array so that you aren't pushing to an undefined object.
items[i].push('a', 'b', 'c');
}
console.log(items);
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.
var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
var point = 'c';
How can I split the "arr" into two arrays based on the "point" variable, like:
['a', 'b']
and
['d', 'e', 'f']
var arr2 = ['a', 'b', 'c', 'd', 'e', 'f'];
arr = arr2.splice(0, arr2.indexOf('c'));
To remove 'c' from arr2:
arr2.splice(0,1);
arr contains the first two elements and arr2 contains the last three.
This makes some assumptions (like arr2 will always contain the 'point' at first assignment), so add some correctness checking for border cases as necessary.
Use indexOf and slice
var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
var indexToSplit = arr.indexOf('c');
var first = arr.slice(0, indexToSplit);
var second = arr.slice(indexToSplit + 1);
console.log({first, second});
Sharing this convenience function that I ended up making after visiting this page.
function chunkArray(arr,n){
var chunkLength = Math.max(arr.length/n ,1);
var chunks = [];
for (var i = 0; i < n; i++) {
if(chunkLength*(i+1)<=arr.length)chunks.push(arr.slice(chunkLength*i, chunkLength*(i+1)));
}
return chunks;
}
Sample usage:
chunkArray([1,2,3,4,5,6],2);
//returns [[1,2,3],[4,5,6]]
chunkArray([1,2,3,4,5,6,7],2);
//returns [[1,2,3],[4,5,6,7]]
chunkArray([1,2,3,4,5,6],3);
//returns [[1,2],[3,4],[5,6]]
chunkArray([1,2,3,4,5,6,7,8],3);
//returns [[1,2],[3,4,5],[6,7,8]]
chunkArray([1,2,3,4,5,6,7,8],42);//over chunk
//returns [[1],[2],[3],[4],[5],[6],[7],[8]]
Try this one:
var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
var point = 'c';
var idx = arr.indexOf(point);
arr.slice(0, idx) // ["a", "b"]
arr.slice(idx + 1) // ["d", "e", "f"]
var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
var point = 'c';
Array.prototype.exists = function(search){
for (var i=0; i<this.length; i++) {
if (this[i] == search) return i;
}
return false;
}
if(i=arr.exists(point))
{
var neewArr=arr.splice(i);
neewArr.shift(0);
console.log(arr); // output: ["a", "b"]
console.log(neewArr); // output: ["d", "e", "f"]
}
Here is an example.
var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
var point = 'c';
var i = arr.indexOf(point);
var firstHalf, secondHalf, end, start;
if (i>0) {
firstHalf = arr.slice(0, i);
secondHalf = arr.slice(i + 1, arr.length);
}
//this should get you started. Can you think of what edge cases you should test for to fix?
//what happens when point is at the start or the end of the array?
When splitting the array you are going to want to create two new arrays that will include what you are splitting, for example arr1 and arr2. To populate this arrays you are going to want to do something like this:
var arr1, arr2; // new arrays
int position = 0; // start position of second array
for(int i = 0; i <= arr.length(); i++){
if(arr[i] = point){ //when it finds the variable it stops adding to first array
//starts adding to second array
for(int j = i+1; j <= arr.length; j++){
arr2[position] = arr[j];
position++; //because we want to add from beginning of array i used this variable
}
break;
}
// add to first array
else{
arr1[i] = arr[i];
}
}
There are different ways to do this! good luck!
Yet another suggestion:
var segments = arr.join( '' ).split( point ).map(function( part ) {
return part.split( '' );
});
now segments contains an array of arrays:
[["a", "b"], ["d", "e", "f"]]
and can get accessed like
segments[ 0 ]; // ["a", "b"]
segments[ 1 ]; // ["d", "e", "f"]
if you want to split into equal half; why no simple while loop ?
var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
var c=[];
while(arr.length > c.length){
c.push(arr.splice(arr.length-1)[0]);
}
Kaboom :).
Separate two arrays with given array elements as string array and number array;
let arr = [21,'hh',33,'kk',55,66,8898,'rtrt'];
arrStrNum = (arr) => {
let str = [],num = [];
for(let i = 0;i<arr.length;i++){
if(typeof arr[i] == "string"){
str.push(arr[i]);
}else if(typeof arr[i] == "number"){
num.push(arr[i]);
}
}
return [str, num]
}
let ans = arrStrNum(arr);
let str = ans[0];
let num = ans[1];
console.log(str);
console.log(num);