This question already has answers here:
Find last index of element inside array by certain condition
(23 answers)
Closed 2 years ago.
Is it possible somehow to use the lastIndexOf method to get the value of a variable in an array of array? For example if I had
[[1,2,3,4],[4,6,4,7,5], [5,7,4,6,3], [6,2,5,4,3]]
and I wanted to find the index of the last array where [1] was 2? In the above I would expect the answer to be 3 as the third array has [1] equal to 2.
I can see how I can make this work with nested loops or array methods but just wondered if there's some syntax I'm not aware of. Cheers
No.
Because Array.prototype.lastIndexOf() only accepts an element, and not a callback, you can't use lastIndexOf() for this case directly.
Given this, and that there's no standard findLastIndex() prototype function, you'll have to write this functionality yourself. Here's one such way, using reduce() and findIndex(), while avoiding mutating the original array:
const arr = [[1,2,3,4],[4,6,4,7,5], [5,7,4,6,3], [6,2,5,4,3]];
function findLastIndex(arr, callback) {
return (arr.length - 1) - // Need to subtract found, backwards index from length
arr.slice().reverse() // Get reversed copy of array
.findIndex(callback); // Find element satisfying callback in rev. array
}
console.log(findLastIndex(arr, (e) => e[1] == 2));
I discovered arr.slice().reverse() from this answer by user #Rajesh, which is much faster than my previous reducer.
Related
This question already has answers here:
Filter and delete filtered elements in an array
(10 answers)
Closed 3 years ago.
I am iterating over an array of strings using forEach(), and testing each element's length to determine wether it is even or odd. If the length of the string is even, it will be removed using splice().
My input and output are shown below, and as you can see even though (i think) my conditions are correct, in my return array, I still get an even, two character word - which should have been spliced out.
Code:
function filterOddLengthWords(words) {
words.forEach(function(element, index) {
if (element.length%2===0) {
words.splice(index, 1);
}
})
return words;
}
var output = filterOddLengthWords(['there', 'it', 'is', 'now']);
console.log(output); // --> [ 'there', 'is', 'now' ]
I understand where the error is, but I just don't know how to compensate for it. I could possibly rewrite this by creating an empty array at the beginning of the function, and then testing each element against the inverse condition, using the push() method to add each positive to the empty array. However, that is more inefficient and I'm curious to see if my way is possible. Thanks for the answers in advance.
By splicing an array, you change the index, but forEach takes the elements in advance and the old indices.
Usually by using splice, the iteration is started from the end and if some item is remoce, the index remains for the items before.
You could filter the array.
function filterOddLengthWords(words) {
return words.filter(function(element) {
return element.length % 2;
});
}
var output = filterOddLengthWords(['there', 'it', 'is', 'now']);
console.log(output);
The problem with splicing the array in the forEach() is that when you splice() on the array at index 1 which has the element it the element at index 2 is is moved to index 1.
So in the next iteration when the index is 2 in the callback the element at the index 2 of the array is the value now instead of the element is. As now is odd it is kept but the element is is completely skipped.
Using Array.prototype.filter will work here as it does not modify the original array but instead collects the valid results into a new array.
This question already has answers here:
How to find first element of array matching a boolean condition in JavaScript?
(14 answers)
Closed 3 years ago.
I may not have had enough coffee on this lovely monday morning but there's something simple I'd like to do that is not coming to me.
I am filtering on an array of objects for an id:
const skuVariant = skuOptions.filter(sku => sku.itemNumber === variantItemNumber);
This returns an array that is of length 1 if there is a match.
The following line I have:
const skuVariantValueMap = skuVariant && skuVariant[0].varianceValueMap;
I would like to not have to check the for the first element of the array and instead only return the object from the call to filter and not the object inside an array.
To be extra clear skuVariant returns this: [{id: 1234}]
I would like it to return this: { id: 1234 }
This is possible using lodash utils but that's overkill. I am looking for something vanilla.
Is there an ES7, ES6 / super clean way of achieving this?
Thanks in advance.
Use Array.prototype.find instead of filter. It returns the value of the first element in the array that satisfies the provided testing function.
This question already has answers here:
Deleting array elements in JavaScript - delete vs splice
(29 answers)
Closed 4 years ago.
I couldn't find a question that specifically targets the issue I'm having hence this question is being asked.
I have an array that holds 5 numbers:
var numbers = [0,1,2,3,4];
Once a number is clicked on the frontend (website), the number is removed from the array using the below code:
delete numbers[1];
This removes the correct number but leaves a space where the number was (the space is undefined). I believe this is causing an issue. After a number is removed from the array, I use another function to randomly pick any of the remaining numbers in the array however it sometimes fails. After much thought, I've realized it may be because there are empty spaces in the array after a number is removed and as a result, the code fails to work due to the undefined element.
Is my analogy correct or am I mistaken?
(I have also attempted to use the splice method to remove the number however that then causes an issue with the length of my array because if I later want to remove another number, it removes the wrong one due to the numbers moving around etc).
What you'd want to use is splice
In your specific case, numbers.splice(1,1)
You're correct that delete replaces one of the values in the array with undefined, and does not change the array length. Later on when you randomly choose an element from the array, you can wind up getting that undefined value, because it's still taking up a slot in the array:
var numbers = [0,1,2,3,4];
delete numbers[3];
console.log(numbers)
Instead use splice, which removes the item from the array completely:
var numbers = [0,1,2,3,4];
numbers.splice(3,1) /// remove one element starting at index 3
console.log(numbers)
if I later want to remove another number, it removes the wrong one due to the numbers moving around
You do need to choose one behavior or the other. If you need to preserve indexes as is, then continue to use delete, leaving the undefined values in the array, and rewrite your "choose one at random" function to never pick undefined values:
// start with some undefined values:
var numbers = [0, 1, undefined, undefined, undefined, 5]
var pickRandom = function(numbers) {
// make a copy of the array, removing undefined elements:
var definedValues = numbers.filter(function(item) {
return item !== undefined;
});
if (definedValues.length === 0) {return false}
//choose one at random:
return definedValues[Math.floor(Math.random() * definedValues.length)]
}
// test it:
console.log(pickRandom(numbers));
console.log(pickRandom(numbers));
console.log(pickRandom(numbers));
console.log(pickRandom(numbers));
(...but note that this suggests that a simple array is the wrong data structure to use here; you may be better off with an array of objects each with an explicit ID, so you can reference specific ones as needed without worrying about keeping the array index the same.)
If you mean to actually remove the element from the array, leaving your array with 4 elements, then you can use
numbers.splice(1);
This will remove the element in the index 1 from the array and return the section of the new array.
This question already has answers here:
Determine whether an array contains a value [duplicate]
(18 answers)
How do I check if an array includes a value in JavaScript?
(60 answers)
Closed 6 years ago.
Does anyone know of a way to check if a list contains a string without using indexOf? In my array some strings can contains parts of others, so indexOf will produce false positives.
As an example, how would I determine if "component" is in the array below?
["component.part", "random-component", "prefix-component-name", "component"]
Update:
It seems like my use of false positive was misleading. I meant that it would say that component was in there 4 times, when I want to match the string by itself.
ie. It should return false when checking for the presence of "component" in the below array.
["component.part", "random-component", "prefix-component-name"]
Use the Array.find API.
Example:
"use strict";
let items = ["component.part", "random-component", "prefix-component-name", "component"];
let found = items.find(item => { return item === "component.part" } );
if (found) {
console.log("Item exists.");
}
For more usage example.
See:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find
One way is to use .find() to get the string you want from the Array.
Try using $.inArray() method.
var list=["component.part", "random-component", "prefix-component-name", "component"];
if($.inArray(" component",list) != -1){
console.log("Item found");
}
Does anyone know of a way to check if a list contains a string without using indexOf? In my array some strings can contains parts of others, so indexOf will produce false positives.
false positives? Array.prototype.indexOf and Array.prototype.includes both use strict equality which makes that impossible here.
IndexOf won't give you false positive. It will give you 3. If you want to find all elements that has "otherstuff componenet" you can loop through your array and check with String.includes()
Here is a beginner friendly solution.
var arr = ["component.part", "random-component",
"prefix-component-name", "component", "asdf"];
console.log(arr.indexOf('component')); // give u 3
for (var i = 0; i < arr.length; i++){
if (arr[i].includes('component')){
console.log(arr[i]);
}
}
This question already has answers here:
How to create an array containing 1...N
(77 answers)
Closed 9 years ago.
I'm brand new to javascript. I was working through a problem earlier where I needed an array that included the numbers 1 thru 20.
I did this with the following:
var numberArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
QUESTION:
I can't help but think that this is not efficient (and certainly not scalable). Is there a way to create an array that automatically populates with sequential values between 1 and 20, or 1 and 1000 for instance?
Here's a oneliner:
var myArr = Array(20).join().split(',').map(function(a){return this.i++},{i:1});
or a tiny bit shorter:
var myArr = (''+Array(20)).split(',').map(function(){return this[0]++;}, [1]);
Both methods create an empty Array with 20 empty elements (i.e. elements with value undefined). On a thus created Array the map method can't be applied 1, so the join (or string addition) and split trick transforms it to an Array that knows it. Now the map callback (see the MDN link) does nothing more than sending an increment of the initial value ({i:1} or [1]) back for each element of the Array, and after that, myArr contains 20 numeric values from 1 to 20.
Addendum: ES20xx
[...Array(21).keys()].slice(1);
Array.map => See also...
See also this Stackblitz project.
1 Why not? See this SO answer, and this one for a more profound explanation
You could use a simple loop to do what you want;
var numberArray = [];
for(var i = 1; i <= 20; i++){
numberArray.push(i);
}
console.log(numberArray);