If I have an array like const fruits = ["apple", "orange", "banana", "apple", "grape", "apple"] how can I use indexOf() (or another function if one exists) to find the index of every match?
Put another way, fruits.indexOf("apple") will only return 0 right now, but I want way to return an array with every matching index: [0, 3, 5].
Answer from mdn , Read the Docs
const indices = [];
const array = ["a", "b", "a", "c", "a", "d"];
const element = "a";
let idx = array.indexOf(element);
while (idx !== -1) {
indices.push(idx);
idx = array.indexOf(element, idx + 1);
}
console.log(indices);
// [0, 2, 4]
Here, inside the while loop, the second argument of indexOf method will determine the starting pointing point for finding index.
And the loop is updating it for next occurrences and storing it in an indices array
You can use .reduce():
const apples = fruits.reduce((result, fruit, index) => {
if (fruit === "apple")
result.push(index);
return result;
}, []);
You could of course wrap that in a function so that you could pass an array and a value to look for, and return the result.
You could use a combination of Array#map and Array#filter methods as follows:
const
fruits = ["apple", "orange", "banana", "apple", "grape", "apple"],
matchFruit = fruit => fruits
.map((f,i) => f === fruit ? i : -1)
.filter(i => i > -1);
console.log( matchFruit( "apple" ) );
Related
I'm trying to filter arr2. If the element doesn't have an ID listed in arr, then I want it to be removed. How could I make this happen in javascript?
var arr= ["a", "b", "d"]
var arr2=[{id:"a", value:1},{id:"b", value:2}, {id:"c", value:3}]
result:
[{id:"a", value:1},{id:"b", value:2}]
Thanks in advance :)
You can use reduce and in the callback function check if arr includes the id of the object under iteration. If so then add the elements in the accumulator array
var arr = ["a", "b", "d"]
var arr2 = [{
id: "a",
value: 1
}, {
id: "b",
value: 2
}, {
id: "c",
value: 3
}];
const newData = arr2.reduce((acc, curr) => {
if (arr.includes(curr.id)) {
acc.push(curr)
}
return acc;
}, []);
console.log(newData)
if arr items are always strings you can do this:
var arr = ["a", "b", "d"];
var arr2 = [{id:"a", value:1},{id:"b", value:2}, {id:"c", value:3}];
let str = arr.join('')
let filtered = arr2.filter(x => str.includes(x.id));
console.log(filtered)
this should do it
var arr= ["a", "b", "d"]
var arr2=[{id:"a", value:1},{id:"b", value:2}, {id:"c", value:3}]
const filteredArray = arr2.filter(obj => {
return arr.includes(obj.id)
})
Using filter, reduce, and includes are all nearly twice as slow as simply using a loop. To walk you through it, all it does is check over every element in the second array and check to see if it's id property is in the first array, and if it is, it clones it. Also, for future reference, that title is written poorly. A much better title would be "How to filter array of objects based on a list of possible ID properties"
var arr= ["a", "b", "d"]
var arr2=[{id:"a", value:1},{id:"b", value:2}, {id:"c", value:3}]
let clone = []
for(let i = 0;i < arr2.length;i++){
for(let j = 0;j < arr.length; j++) if(arr2[i].id === arr[j]) clone.push(arr2[j])
}
console.log(clone)
I want to find and count the pair of values within an array.
For example:
var Array = ["Apple", "Pear", "Mango", "Strawberry", "Apple", "Pear", "Orange"];
Now I want to count how many times each pair (Apple and Pear, Pear and Mango and so on...) occurs in the array. If the array has uneven pair, the last value should then be zero.
The output of the array in the example should then be:
[2,1,1,1,1]
Notice that the "Apple, Pear" occurs 2 times so then the count will be two and put in the first number of the new array.
I hope I explained good enough
You could use a hash table for counting pairs by using two adjacent values and build a key of it for counting. Then use the values as result.
var array = ['Apple', 'Pear', 'Mango', 'Strawberry', 'Apple', 'Pear', 'Orange'],
count = {},
result;
array.reduce((a, b) => {
var key = [a, b].join('|');
count[key] = (count[key] || 0) + 1;
return b;
});
result = Object.values(count);
console.log(result);
console.log(count);
You could use sort() taking advantage of the fact that it passes the pairs needed to the callback:
var arr = ["Apple", "Pear", "Mango", "Strawberry", "Apple", "Pear", "Orange"];
var pairs = {}
arr.sort((a,b)=>{
(a+b in pairs)?pairs[a+b]++:pairs[a+b] = 1;
})
console.log(Object.values(pairs))
This is the simplest way to do it. It is similar to the answer given by #Nina Scholz above, but without having to join or anything like that. Also note that, while it defaults to pairs (i.e., 2), it is generic enough to check for triples, quadruples, and so on:
function CountMultiples(inputArray, quantity = 2) {
var count = {};
return inputArray.reduce((acc, val) => {
count[val] = (count[val] || 0) + 1;
return count[val] % quantity > 0 ? acc : ++acc;
}, 0);
};
var a = [1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 0, 0, 0, 6];
console.log(CountMultiples(a,4));//0
console.log(CountMultiples(a,3));//1
console.log(CountMultiples(a));//4
I'm in need of little help with records matching in two arrays with different length.
Requirements:
Find same values between two arrays
Return only that matched
Push matched value back to the array where the values were found.
Example:
var findFrom = ["Apple", "Mango", "Orange", "Mango", "Mango", "Apple"];
var findTheseValues = ["Apple", "Mango"];
Returned Array = ["Apple", "Apple("Matched")", "Orange", "Mango", "Mango("Matched")", "Mango", "Mango(Matched)", "Apple("Matched")"];
**// Push matched values next to the value that was matched in the FindFrom Array**
I tried:
var findFrom = ["Apple", "Mango", "Orange", "Banana", "Orange", "Orange","Orange"];
var findTheseValues = ["Orange", "Banana"];
for(let i = 0; i < findFrom.length; i++){
if (findFrom[i] === findTheseValues[i] // toString() if required){
console.log(findFrom[i]);
}
}
If I just replace the 'i' in the if condition for find These Values with 0, it returns the matched values but I don't want it to match just one value - it should loop over both arrays.
Tried Find from ES 6 but it just returns one value that matched.
I'm happy to explain more if required & I appreciate the help! :)
You can use .map() and .includes() methods:
let findFrom = ["Apple", "Mango", "Orange", "Mango", "Mango", "Apple"],
findTheseValues = ["Apple", "Mango"];
let result = findFrom.map(s => s + (findTheseValues.includes(s) ? ` (${s})` : ''));
console.log(result);
Docs:
Array.prototype.map()
Array.prototype.includes()
This solution works for me:
var findFrom = ["Apple", "Mango", "Orange", "Mango", "Mango", "Apple"];
var findTheseValues = ["Apple", "Mango"];
var solution = [];
for(let i = 0; i < findFrom.length; i++){
solution.push(findFrom[i]);
if (findTheseValues.indexOf(findFrom[i]) !== -1) {
solution.push(findFrom[i] + ' (Matched)');
}
}
console.log(solution)
This loops through the array, tries to find the element at the index in "findthesevalues"- then pushes the "matched" string to the new array if we find a match
You can use Arrays map method which return a new set of array with matched text appended.
var returnedArray = findFrom.map((ele)=> {
if(findTheseValues.indexOf(ele)!==-1){
return [ele, ele+"(matcheed)"] // return a pair with appended matched
}else{
return ele;
}
}).join().split(',') // to flatten array.
Here's a decent solution that uses native Array methods instead of for-loops, which is always a better idea, imho.
Also, this will also allow you to look for the same value more than once, e.g. include a value more than once in your search.
let findFrom = ["Apple", "Mango", "Orange", "Mango", "Mango", "Apple"];
// try either of the following
let findTheseValues = ["Apple", "Mango"];
//let findTheseValues = ["Apple", "Mango", "Mango"];
let results = [];
findFrom.forEach((i) => {
const match = findTheseValues.filter((a) => i === a);
const result = match.length > 0 ? match.concat(i) : i;
results.push(i);
if (match.length > 0) {
match.forEach(m => results.push(m));
};
});
console.log(results);
I would do something like this
var findFrom = ["Apple", "Mango", "Orange", "Mango", "Mango", "Apple"];
var findTheseValues = ["Apple", "Mango"];
var matches = findFrom.map((e, i)=>{
return r = findTheseValues.includes(e) ? e + '(matched)' : e;
});
console.log(matches);
I am writing this answer because all other solutions proposed are based on linear searching over findTheseValues array, whereas the total computational complexity can be definitely reduced using a different data structure: I am talking about Sets or Maps. They are probably implemented using a hash table and as ECMAScript Standard says:
must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection.
So, my solution is almost equal to the others, except for data structure used.
let findTheseValuesSet = new Set(findTheseValues);
let newArray = [];
findFrom.forEach(elem => {
newArray.push(elem);
if (findTheseValuesSet.has(elem))
newArray.push(elem + '(Matched)');
});
For example i have an array
var fruits = ["Banana", "Orange", "Apple", "Mango", "App", "Man"];
The code
fruits.splice(2, 2);
Return me output
Banana,Orange,App,Man
But how to return only 1,3,4 elements from array without looping?
So i will get
Orange,Mango,App
I imaging must be something like that
fruits.splice( fruits.indexOf(Orange,Mango,App), 1 );
You can use filter to filter out certain items:
fruits = fruits.filter(function (e, i) {
return i === 1 || i === 3 || i === 4;
});
Or if you want to keep certain items based on their identity (which seems to be what you're trying to do at the end of your question):
fruits = fruits.filter(function (e) {
return e === "Orange" || e === "Mango" || e === "App";
});
The same as JLRishe's answer but with the addition that you can pass in a list of those elements that you want to keep:
var fruits = ["Banana", "Orange", "Apple", "Mango", "App", "Man"];
var list = 'Orange, Mango, App';
alert(strip(fruits, list)); // ["Orange", "Mango", "App"]
function strip(arr, list) {
list = list.split(', ');
return arr.filter(function (el) {
return list.indexOf(el) > -1;
});
}
You may combine slice and splice methods:
var fruits = ["Banana", "Orange", "Apple", "Mango", "App", "Man"];
fruits.splice(2,1);
var x = fruits.slice(1,4);
x;
Explanation:
splice deletes 1 element starting at index 2 ( ie. "Apple" ).
slice extracts 3 elements starting at index 1 ( ie. "Orange", "Apple", "Mango", "App"; remember that at this time, the array no longer contains "Apple").
Variation (non-destructive):
var fruits = ["Banana", "Orange", "Apple", "Mango", "App", "Man"];
var x = fruits.slice(1,2).concat(fruits.slice(3,5));
x;
is there an AngularJS way of checking if a value exists in an array
var array1 = ["a","b","c"]
i'm trying to do this..
var array2 = ["c", "d", "e"]
angular.forEach(array2, function (a) {
if (a /*is NOT in array1*/) {
array1.push(a);
} else {
return false
}
});
You can use Array.indexOf which will return -1 if it's not found or the index of the value in the array.
So in your case:
if (array2.indexOf(a) < 0) {
array1.push(a);
}
You just need to use native Array.prototype.indexOf to check if value is in array or not:
var array2 = ["c", "d", "e"]
angular.forEach(array2, function (a) {
if (array2.indexOf(a) === -1) {
// a is NOT in array1
array1.push(a);
}
});
https://www.w3schools.com/jsref/jsref_includes_array.asp
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var n = fruits.includes("Mango");