I have 2 arrays, one of which is filled with elements and the other has empty elements, eg:
let arr1 = ['apples', 'bananas', 'oranges', 'strawberries', 'blueberries', 'pineapple']
let arr2 = [1,,3,,,4]
How do I remove both bananas, strawberries and blueberries and the empty element in arr2, should look something like this:
let arr1 = ['apples', 'oranges', 'pineapple']
let arr2 = [1,3,4]
edit: added more elements to the array for scale.
You could map and filter with true because filter omits sparse items.
let array1 = ['apples', 'bananas', 'oranges'],
array2 = [1, , 3],
result1 = array2.map((_, i) => array1[i]).filter(_ => true),
result2 = array2.filter(_ => true);
console.log(result1);
console.log(result2);
You can use Array.prototype.filter():
let arr1 = ['apples', 'bananas', 'oranges', 'strawberries', 'blueberries', 'pineapple'];
let arr2 = [1,,3,,,4];
arr1 = arr1.filter((x, i) => arr2[i] !== undefined);
arr2 = arr2.filter(x => x !== undefined);
console.log(arr1);
console.log(arr2);
you can iterate and return only the expected value something like the below snippet
After edit please follow the below snippet
let arr1 = ['apples', 'bananas', 'oranges']
let arr2 = [1, , 3]
var filtered = arr2.filter((item, index) => {
if (arr2[index] != null) {
arr1.splice(index, index);
return true;
} else {
return false
}
});
console.log(filtered);
console.log(arr1);
You can use filter()
let arr1 = ['apples', 'bananas', 'oranges', 'strawberries', 'blueberries', 'pineapple']
let arr2 = [1,,3,,,4]
let result = arr1.filter((item, index) => {
return arr2[index] !== undefined;
});
console.log(result); // Outputs: ["apples", "oranges", "pineapple"]
Check this fiddle.
const filterOutItems = (array, itemValue = undefined) {
if (typeof itemValue == undefined) {
return array.filter((el) => !!el);
} else {
return array.filter((el) => el != itemValue);
}
}
The filter method will return only the items that satisfy the predicate.
Related
I have two array of objects arr 1 and arr 2
arr1 = [{fruit: 'apple',count: 0}] arr2 = [{fruit: 'apple',count: 0}]
Need to create the function which accepts arr1 and arr2 as arguments and compare the fruit name if its same need to update the count value based on the count input else push the value to the array
sample output 1:
Inputs:
arr1 = [{fruit: 'apple',count: 10}] arr2 = [{fruit: 'apple',count: 30},{fruit: 'orange',count: 20}]
Output:
[{fruit: 'apple',count: 40},{fruit: 'orange',count: 20}]
sample output2
Inputs:
arr1 = [{fruit: 'apple',count: 15}] arr2 = [{fruit: 'orange',count: 20}]
Output:
[{fruit: 'apple',count: 15},{fruit: 'orange',count: 20}]
code that i have tried:
function compareAndUpdateCount(arr1, arr2) {
for (i = 0; i < arr1.length; i++) {
if (arr1[i].fruit === arr2[i].fruit) {
arr1[i].count = arr1[i].count + arr2[i].count;
} else {
arr1.push(arr2[i])
}
}
}
This works fine when the array lengths are same ,if its different need help on writing the optimise code and also the reduce time complexity if we have more data
You will need a setter for count in your class
Make a new array of objects temparr
temparr[0] = arr1[0];
if((arr1[0].fruit).equals(arr2[0].fruit)) {
temparr[0].setcount(arr1[0].count+arr2[0].count);
}
else {
temparr[1]=arr2[0];
}
At the end u print temparr
You can easily achieve the result using Map and reduce
function groupObject(arr1, arr2) {
const map = new Map();
const temp = [...arr1, ...arr2].reduce((acc, { fruit, count }) => {
map.has(fruit)
? (map.get(fruit).count = map.get(fruit).count + count)
: map.set(fruit, { fruit, count });
return acc;
}, map);
return [...map.values()];
}
const arr1 = [{ fruit: "apple", count: 15 }];
const arr2 = [{ fruit: "orange", count: 20 }];
console.log(groupObject(arr1, arr2));
const arr3 = [{ fruit: "apple", count: 0 }];
const arr4 = [{ fruit: "apple", count: 0 }];
console.log(groupObject(arr3, arr4));
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
var result;
if(arr1.length < 1) {
result = arr2;
} else if(arr2.length < 1) {
result = arr1;
} else {
var existing = [];
var arr3 = [];
arr1.forEach(function (item, index) {
arr2.forEach(function (item2, index2) {
if(item.fruit === item2.fruit) {
item.count = item.count + item2.count;
existing.push(index2);
} else {
arr3.push(item);
if(!existing.includes(index2)) {
arr3.push(item2);
}
}
});
});
result = arr3;
}
Loop within another loop to compare all object properties and then use an if statement to sum up the counter and remove the item of the second array using splice()
Try the following snippet:
var arr1 = [{fruit: 'apple',count: 10}];
var arr2 = [{fruit: 'apple',count: 30}, {fruit: 'orange',count: 20}, {fruit: 'apple',count: 20}, {fruit: 'banana',count: 20}];
var counter = 0;
for(obj1 in arr1){
for(obj2 in arr2){
if (arr1[obj1].fruit === arr2[obj2].fruit) {
arr1[obj1].count = arr1[obj1].count + arr2[obj2].count;
arr2.splice(counter, 1);
counter++;
}
}
}
arr1 = arr1.concat(arr2);
console.log(arr1)
Try using reduce to group the fruits along with its count, followed by a simple map to get the required array
const arr1 = [{fruit: 'apple',count: 10}] , arr2 = [{fruit: 'apple',count: 30},{fruit: 'orange',count: 20}]
const res = [...arr1, ...arr2].reduce((acc, curr) => {
acc[curr.fruit]
? (acc[curr.fruit].count += curr.count)
: (acc[curr.fruit] = curr);
return acc;
}, {});
console.log(Object.keys(res).map((item) => res[item]));
If I have two arrays, in Javascript:
let arr1 = ["Dog", "Cat", "Monkey", "Zebra", "Goat", "Goose"];
let arr2 = ["Zebra", "Goat"];
How can I find the indexes of the larger array where there is a match and store them in another array so example output would be:
let indexes = [3,4]
You could do it by mapping over your search-teams (arr2) and then using the findIndex Method on the source-array (arr1) like this:
let arr1 = ["Dog", "Cat", "Monkey", "Zebra", "Goat", "Goose"];
let arr2 = ["Zebra", "Goat"];
const result = arr2.map(searchTerm => arr1.findIndex((compareTerm) => compareTerm === searchTerm));
console.log(result);
You can achieve the expected output using Array.map and Array.findIndex
let arr1 = ["Dog", "Cat", "Monkey", "Zebra", "Goat", "Goose"];
let arr2 = ["Zebra", "Goat"];
const findIndexes = (param1, param2) => {
let arr1 = [...param1];
let arr2 = [...param2];
//swap the arrays if the no.of array elements
//in the second array are greater than first
if(arr1.length < arr2.length) {
[arr1, arr2] = [arr2, arr1];
}
//Loop through all the items of the smaller array
//check if the element is present in the bigger array
return arr2.map(a2 => arr1.findIndex(a1 => a1 === a2));
}
console.log(findIndexes(arr1, arr2));
//here for "test", we'll get index as -1, because
//if the matching element is not found, findIndex will
//return -1
let arr3 = ["Cat", "Goose", "test"];
console.log(findIndexes(arr3, arr1));
If you wish to get the indexes of the elements that are found and wish to filter out all the -1s, below is the code for the same.
let arr1 = ["Dog", "Cat", "Monkey", "Zebra", "Goat", "Goose"];
let arr2 = ["Zebra", "Goat"];
const findIndexes = (param1, param2) => {
let arr1 = [...param1];
let arr2 = [...param2];
if(arr1.length < arr2.length) {
[arr1, arr2] = [arr2, arr1];
}
return arr2.map(a2 => arr1.findIndex(a1 => a1 === a2)).filter(ele => ele !== -1);
}
console.log(findIndexes(arr1, arr2));
let arr3 = ["Cat", "Goose", "test"];
console.log(findIndexes(arr3, arr1));
let arr1 = ["Dog", "Cat", "Monkey", "Zebra", "Goat", "Goose"];
let arr2 = ["Zebra", "Goat"];
let indexes = []
arr1.forEach((item, index) => {
if(arr2.includes(item)){
indexes.push(index)
}
})
console.log(indexes)
So i currently have an array like this:
const allMeats = ['Bacon','Bacon','Bacon', 'Steak', 'Lettuce', 'Cabbage','Cabbage','Cabbage','Steak', 'Veal']
I would like to morph the array so that it becomes an array of objects with key/vals that determine the value of the duplicates.
Currently i have got
const meatsGrouped = allMeats.reduce(
(acum, cur) => Object.assign(acum, { [cur]: (acum[cur] || 0) + 1 }),
[],
);
however this code turns the array int this:
[Bacon: 3, Steak: 2, Lettuce: 1, Cabbage: 3, Veal: 1]
when ideally i want it to look like this:
[{Bacon: 3}, {Steak: 2}, {Lettuce: 1}, {Cabbage: 3}, {Veal: 1}]
Can any1 please tell me what i'm doing wrong/missing?
You could do it using reduce and map method.
const allMeats = [
'Bacon',
'Bacon',
'Bacon',
'Steak',
'Lettuce',
'Cabbage',
'Cabbage',
'Cabbage',
'Steak',
'Veal',
];
const ret = Object.entries(
allMeats.reduce((prev, c) => {
const p = prev;
const key = c;
p[key] = p[key] ?? 0;
p[key] += 1;
return p;
}, {})
).map(([x, y]) => ({ [x]: y }));
console.log(ret);
You can do the following using reduce method,
let allMeats = ['Bacon','Bacon','Bacon', 'Steak', 'Lettuce', 'Cabbage','Cabbage','Cabbage','Steak', 'Veal'];
let res = allMeats.reduce((prev, curr) => {
const index = prev.findIndex(item => item.hasOwnProperty(curr));
if(index > -1) {
prev[index][curr]++;
}else {
prev.push({[curr]: 1});
}
return prev;
}, []);
console.log(res);
I have a 2D array and a function that will return the index of value Q. How can I write the function so that I can get AllIndexOfQ? So if I am looking for "dog" I will get [0,0],[1,2],[3,1],[3,2]
var arr = Array(['dog', 'cat', 'fish'], ['fish', 'fish', 'dog'], ['cat', 'tiger', 'fish'], ['cat', 'dog', 'dog']);
function getIndexOfQ(data, q) {
for (var i = 0; i < data.length; i++) {
var index = data[i].indexOf(q);
if (index > -1) {
return [i, index];
}
}
}
var a = getIndexOfQ(arr, "dog");
console.log(a);
Don't return, push to an array instead. Also, indexOf isn't enough, because that won't find all matches, just the first match. You'll have to iterate over each item of the sub-array, and if it matches, push an array of the two indicies to the matches array:
var arr = Array(['dog', 'cat', 'fish'], ['fish', 'fish', 'dog'], ['cat', 'tiger', 'fish'], ['cat', 'dog', 'dog']);
function getIndexOfQ(data, q) {
const matches = [];
data.forEach((arr, i) => {
arr.forEach((item, j) => {
if (item === q) {
matches.push([i, j]);
}
});
});
return matches;
}
var a = getIndexOfQ(arr, "dog");
console.log(a);
arr.indexOf(searchElement[, fromIndex]) according to MDN.
Which means you can loop through your array and specify a starting point each time to find all occurances.
Tricky to write a one-liner for multiple matches
const arr = [['dog', 'cat', 'fish'], ['fish', 'fish', 'dog'], ['cat', 'tiger', 'fish'], ['cat', 'dog', 'dog']];
const getIndexOfQ = (data, q) => {
let matches = [];
data.forEach((a, i) => {
a.forEach((item, j) => { if (item === q) matches.push([i, j]) })
})
return matches;
};
const a = getIndexOfQ(arr, "dog");
console.log(a);
Try this if you only want to find one dog in each array
const arr = [['dog', 'cat', 'fish'], ['fish', 'fish', 'dog'], ['cat', 'tiger', 'fish'], ['cat', 'dog', 'dog']];
const getIndexOfQ = (data, q) => data.map(
(item,i) => (item.indexOf(q) !==-1) ? [i,item.indexOf(q)] : false)
.filter(item => item);
const a = getIndexOfQ(arr, "dog");
console.log(a);
I'm trying to get this nested array to a flat array. While using this way to solve it seems every time I callback arrayFlattener(element) the newArr become a empty array. Can someone help me with this? Thank you.
const arrayFlattener = (arr) => {
let newArr = [];
for (let i = 0; i < arr.length; i++) {
let element = arr[i];
if (Array.isArray(element)){
newArr.push(arrayFlattener(element));
} else {
newArr.push(element);
}
}
return newArr;
}
console.log(arrayFlattener(['I', 'am', 'working', ['on', 'another', 'level']]));
flat do the job with the depth param level specifying how deep a nested array structure should be flattened.
Example
const arr = ['I', 'am', 'working', ['on', 'another', 'level'], 'now', ["now", ["hello", "you you"]]]
console.log(arr.flat(2))
Your code and theory are fine. You just chose the wrong method. Use concat instead of push (to extend the result rather than insert into it):
const arrayFlattener = (arr) => {
let newArr = [];
for (let i = 0; i < arr.length; i++) {
let element = arr[i];
if (Array.isArray(element)){
newArr = newArr.concat(arrayFlattener(element));
} else {
newArr.push(element);
}
}
return newArr;
}
console.log(arrayFlattener(['I', 'am', 'working', ['on', 'another', 'level']]));
You can use flatMap
let newArr = ['I', 'am', 'working', ['on', 'another', 'level']].flatMap(el=>el);
console.log(newArr);
or use flat
var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2); // depth argument to flatten the array
// [1, 2, 3, 4, 5, 6]
Currently, your function did not flatten the array, but simply parse through every individual element of the array. It still returns the same array structure.
To flatten the array, you should pass the resulting array as well, so that the individual element can be pushed straight into the resulting array instead of making another array and push it to the resulting array (which produce the same initial array structure)
let newArr = [];
const arrayFlattener = (arr, result) => {
for (let i = 0; i < arr.length; i++) {
let element = arr[i];
if (Array.isArray(element)){
result = arrayFlattener(element, result);
} else {
result.push(element);
}
}
return result
}
console.log(arrayFlattener(['I', 'am', 'working', ['on', 'another', 'level'], 'now'], newArr));
Here's three solutions
You can use .flatMap and recursion or
const flatten = (xs) =>
Array.isArray(xs) ? xs.flatMap(flatten) : [xs]
const array = ['I', 'am', 'working', ['on', 'another', ['level']]]
console.log(flatten(array))
you can use .reduce and recursion
const flatten = (xs) =>
xs.reduce(
(y, x) => y.concat(Array.isArray(x) ? flatten(x) : [x]),
[])
const array = ['I', 'am', 'working', ['on', 'another', ['level']]]
console.log(flatten(array))
or even better just use .flat
const flatten = (xs) =>
xs.flat(Infinity)
const array = ['I', 'am', 'working', ['on', 'another', ['level']]]
console.log(flatten(array))