This question already has an answer here:
Start from second item in forEach loop
(1 answer)
Closed 5 years ago.
Can this be done without mutating the array?
let arr = [1, 2, 3, 4, 5];
arr.shift() // works but mutates the array
arr.forEach(function(value) {
console.log(value)
});
2
3
4
5
You could use Array#slice for a copy without the first element.
let arr = [1, 2, 3, 4, 5];
arr.slice(1).forEach(function(value) {
console.log(value);
});
Use index in the forEach:
let arr = [1, 2, 3, 4, 5];
arr.forEach(function(value, index) {
if ( index != 0 ) {console.log(value) }
});
Though array.slice(1).forEach(...) is elegant, it does create a new array. You can avoid doing this by checking whether the second property passed to forEach (the array index) is 0, or "falsy." If your passed function happens to only execute a single expression, you can shorten the statement:
if (i) expression() to i && expression()
...which makes this method surprisingly terse.
let array = [1, 2, 3, 4, 5]
array.forEach(function (value, i) {
if (i) console.log(value)
})
array.forEach(function (value, i) {
i && console.log(value)
})
let arr = [1, 2, 3, 4, 5];
arr.forEach(function(value, index) {
return index == 0 ? true : console.log(value), true;
});
arr.forEach(function(value, index) {
if(index !== 0) {
console.log(value);
}
});
this little if statement just fires if the value is not equal to the first array item
Related
const numbers = [1, 2, 3, 4];
const filteredNumbers = numbers.map((num, index) => {
if (index < 3) {
return num;
}
});
// filteredNumbers is [1, 2, 3, undefined]
According to my understanding callback function should return all numbers of array if their index is less than 3 so it should return 1,2,3 and stop after that and number 4 can not be returned as if condition says index should be less than 3.
I am wondering why it returned undefined for index 3 number.
.map is an isomorphism and preserves the length of the given array.
So if the callback function does not return anything, the index will be undefined.
You want to user a filter function instead if you need to filter array elements that meet a certain condition.
const numbers = [1, 2, 3, 4];
const filteredNumbers = numbers.filter((_, index) => index < 3);
console.log(filteredNumbers);
If you want just to get the first 3 items in the array, I recommend using slice.
const numbers = [1, 2, 3, 4];
console.log(numbers.slice(0, 3));
Second solution is use filter instead of map.
const numbers = [1, 2, 3, 4];
const filteredNumbers = numbers.filter((num, index) => {
return index < 3
});
console.log(filteredNumbers)
Trying to solve this Codwars Kata.
Given an array, find the duplicates in that array, and return a new array of those duplicates. The elements of the returned array should appear in the order when they first appeared as duplicates.
Examples:
[1, 2, 4, 4, 3, 3, 1, 5, 3, '5'] ==> [4, 3, 1]
[0, 1, 2, 3, 4, 5] ==> []
I have:
function duplicates(arr) {
arr.sort((value, index) => value - index);
let duplicates = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] === arr[i + 1]) {
duplicates.unshift(arr[i]);
}
}
//filter out duplicates within "duplicates"
duplicates = duplicates.filter((value, index) =>
duplicates.indexOf(value) == index);
return duplicates;
}
console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5']));
This is passing all tests except for one:
Expected: '[1, 4]', instead got: '[4, 1]'
And I'm not sure why - unfortunately it does not display the test case.
It was suggested that another way to create a frequency map, however, is with Map. How would I do this?
I tried:
function duplicates(arr) {
let map = new Map([arr]);
return map;
}
console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5']));
and this doesn't create a frequency map.
What other suggestions would you have?
NOTE - "5" and 5 should not count as the same value.
EDIT - Initially, tried to create a frequencyMap like this:
function duplicates(arr) {
let map = {};
arr.forEach((value, index) => {
if (!map[value]) {
map[value] = 0;
}
map[value] += 1;
})
return map;
}
console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5']));
But in this case, "5" and 5 are considered to be the same value. I don't know how else to check for duplicates - sorting disrupts the order in which the duplicates appear; and creating a frequencyMap count numbers and strings as the same thing.
Here's an idea that should work:
Create a Map (map keys distinguish type so 5 is a different key than "5")
Use filter to go through the items in your array. As you go through keep count of how many times you've seen an item in your Map. Return true from the filter only when the count (before you've increased it) is 1. That's the second time you've seen that item.
The filter should return your answer:
function duplicates(arr) {
let counts = new Map()
return arr.filter(n => {
let count = counts.get(n)
counts.set(n, count ? count+1 : 1)
return count === 1
})
}
console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5']));
Might not be the most efficient solution, but it solves the challenge. Note, I'm using js object to mimic a Map
function duplicates(arr) {
// TODO: return the array of duplicates from arr
const map = {};
const dup = {};
for (const val of arr) {
let key = val;
if (typeof val === 'string') {
key = `${val}_str`;
}
if (map[key]) {
dup[val] = true;
} else {
map[key] = true;
}
}
return Object.keys(dup)
.map( d => (!Number.isInteger(parseInt(d))) ? d : Number(d));
}
console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5']));
I have a dynamically generated multidimensional array from which I want to remove a specific value.
I have this code, so far:
mainARR = [[1,2,3,4], [5,6,7,8]];
delARR = [1,2,3,4];
function removeByValue(array, value){
return array.filter(function(elem, _index){
return value != elem;
});
}
mainARR = removeByValue(mainARR, delARR);
console.log(JSON.stringify(mainARR));
I don't know the index of the value I want to remove. Instead, I know the actual value. The code does not work when the value is an array. It works perfectly for simple arrays like [1,2,3,4] when I want to remove, let's say, the value 1.
Any help is appreciated.
If you make the elem and value into a string then your code works just fine.
function removeByValue(array, value) {
return array.filter(function(elem, _index) {
return value.toString() != elem.toString();
});
}
Example below
mainARR = [
[1, 2, 3, 4],
[5, 6, 7, 8]
];
delARR = [1, 2, 3, 4];
function removeByValue(array, value) {
return array.filter(function(elem, _index) {
return value.toString() != elem.toString();
});
}
mainARR = removeByValue(mainARR, delARR);
console.log(JSON.stringify(mainARR));
You will have to compare every element inside array.
Example solution:
mainARR = [[1,2,3,4], [5,6,7,8]];
delARR = [1,2,3,4];
function removeByValue(array, value){
return array.filter(function(elem, _index){
// Compares length and every element inside array
return !(elem.length==value.length && elem.every(function(v,i) { return v === value[i]}))
});
}
mainARR = removeByValue(mainARR, delARR);
console.log(JSON.stringify(mainARR));
This should work on sorted and unsorted arrays.
You could filter the values and then delete empty arrays as well.
var mainARR = [[1, 2, 3, 4], [5, 6, 7, 8]],
delARR = [1, 2, 3, 4],
result = mainARR.map(a => a.filter(b => !delARR.includes(b))).filter(a => a.length);
console.log(result);
Does anyone know how to remove duplicates in an array including the original value? I came across different snippets like this
and this and some others but none in particular is removing the original node at the same time. Care to share a little snippet ? TIA!
Example:
[1, 1, 2, 3, 5, 5] -> [2, 3]
You could use a check for index and last index.
var arr = [1, 1, 2, 3, 5, 5],
res = arr.filter((a, _, aa) => aa.indexOf(a) === aa.lastIndexOf(a));
console.log(res);
You could try filtering your array based on the number of occurrences of a specific value in that array:
var arr = [1, 1, 2, 3, 5, 5]
var res = arr.filter((el, _, arr) => {
return arr.filter(el2 => el2 === el).length === 1
})
console.log(res)
You might also do as follows;
function removeDuplicates(a){
return a.sort((a,b) => a - b)
.reduce((p,c,i,a) => c === a[i-1] || c === a[i+1] ? p : p.concat(c),[]);
}
var arr = [5,3,2,7,6,6,9,2,4,6,0,8,1,3,8,8,3];
console.log(removeDuplicates(arr))
$(function() {
var array = [1, 2, 3, 4, 5, 6, 6 ,6 ]
console.log(removeDuplicate(array, 6))
});
function removeDuplicate(original, val) {
if(!val) return original
var filtered = _.filter(original, function(num){ return num != val; });
return filtered
}
<script src="http://underscorejs.org/underscore.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Problem:
Compare two arrays and return a new array with any items not found in both of the original arrays. Use Array.filter and Array.indexOf to solve this.
function diff(arr1, arr2) {
var newArr = [];
//code here
return newArr;
}
diff([1, 2, 3, 5], [1, 2, 3, 4, 5]);
I am not sure how to proceed. My solution is different from the above and uses a hard coded array. How do I make mine generic ?
function arrayNotContains(element){
var arr = [1, 2, 3, 5];
if(arr.indexOf(element) === -1){
return true;
}else{
return false;
}
}
var filtered = [1, 2, 3, 4, 5].filter(arrayNotContains);
console.log(filtered);
I got one more solution below. Is that ok ?
var arr1 = [1,2,3,5];
var arr2 = [1,2,3,4,5];
var filtered = arr2.filter(function(num) {
if (arr1.indexOf(num) === -1) return num;
});
You will want to use a closure:
function notContainedIn(arr) {
return function arrNotContains(element) {
return arr.indexOf(element) === -1;
};
}
var filtered = [1, 2, 3, 4, 5].filter(notContainedIn([1, 2, 3, 5]));
console.log(filtered); // [4]
Notice this is just a generalised version of your solution, I'm not saying that this is actually a valid solution for a symmetric diff function. For that, as it was stated in your problem, you'd need to do something like
function symmDiff(a, b) {
return a.filter(notContainedIn(b)).concat(b.filter(notContainedIn(a)));
}