I have a set of data which is nested arrays, these arrays may be empty or they may infact contain an ID, if one of the arrays ID's matches the ID im comparing it with, I want to take all of the data inside that array which matched and assign it to a variable to be used...
example:
data = [[],[],[],[],[],[],[],[],[{"id":"123","name":"DARES HOUSE 2019","startDate":null,"endDate":null,"country":null,"city":null,"type":"Event","members":null}],[],[],[],[],[],[],[],[],[],[],[]]
id = 123
matchedArray =
for (var i = 0; i < potentialEvents.length; i++) {
for (var j = 0; j < potentialEvents[i].length; j++) {
if (id === potentialEvents[i].id) {
return;
}
}
}
console.log(matchedArray)
I'm trying to have it so matchedArray will be the array with thhe matched IDs!!
if you can help, thank you a lot!
You can do this with a combination of .map, .filter and .flat
var data = [[],[],[],[],[],[],[],[],[{"id":"123","name":"DARES HOUSE 2019","startDate":null,"endDate":null,"country":null,"city":null,"type":"Event","members":null}],[],[],[],[],[],[],[],[],[],[],[]]
var id = 123;
var matchedArray = data.map( arr => {
return arr.filter(x => x.id == id);
}).flat();
console.log(matchedArray);
You can use Array#filter method to filter the inner array and Array#flatMap method to concatenate filtered array into one.
let data = [[],[],[],[],[],[],[],[],[{"id":"123","name":"DARES HOUSE 2019","startDate":null,"endDate":null,"country":null,"city":null,"type":"Event","members":null}],[],[],[],[],[],[],[],[],[],[],[]];
let id = 123;
let matchedArray = data.flatMap(arr => arr.filter(obj => obj.id == id))
console.log(matchedArray)
I'd recommend to use .some rather then .filter/.map/.flatMap. The main benefit is that it allows to stop traversing array when element is found.
On big arrays with a lot of data it will be more efficient (≈50 times faster): jsperf test
const data = [[],[],[],[],[],[],[],[],[{"id":"123","name":"DARES HOUSE 2019","startDate":null,"endDate":null,"country":null,"city":null,"type":"Event","members":null}],[],[],[],[],[],[],[],[],[],[],[]]
const id = 123;
let matchedArray = null;
data.some((a) => {
return a.some((v) => {
if (v != null && v.id == id) {
matchedArray = a;
return true;
}
});
});
console.log(matchedArray);
Related
Ok, so I want to return the elements that are present in both provided arrays having the same index location.
exe1 = [A,B,C,D,N]
exe2 = [B,D,C,A,T]
it should return only C
I've tried looping them by nested loops but doesn't work, here is what I've tried:
let testing = []
for (let i = 0; i < exe1.length; i++){
for(let j = 0; j < exe2.length; j++){
if(exe1[i] === exe2[j]){
testing.push(exe1[i])
}
}
};
return testing;
mind the names of the arrays, please
You can use a simple filter to only include values in exe1 that have the same value at the same index of exe2.
const exe1 = ['A','B','C','D','N'];
const exe2 = ['B','D','C','A','T'];
const testing = exe1.filter((val, i) => val === exe2[i]);
console.log(testing)
If you want to create a function that can do this and the datatypes are primitives you can do something like this. Just a loop that goes through each index, checks both arrays, and returns the value that is the same.
const exe1 = ["A","B","C","D","N"];
const exe2 = ["B","D","C","A","T"];
function getElementsThatAreTheSame(arr1, arr2) {
const minLength = Math.min(arr1.length, arr2.length);
const sameArray = [];
for (let i = 0; i < minLength; i++) {
const item1 = arr1[i];
const item2 = arr2[i];
if (item1 == item2) sameArray.push(item1);
}
return sameArray;
}
const sameItems = getElementsThatAreTheSame(exe1, exe2);
console.log(sameItems)
However you could also use the filter method to accomplish this pretty easily as follows:
const exe1 = ["A","B","C","D","N"];
const exe2 = ["B","D","C","A","T"];
const sameArr = exe1.filter((e, i) => exe2[i] == e);
console.log(sameArr);
the filter method will take a function as an argument to which is passed the element in the array and the index of that element. We can just check the second array at that index and make sure it is the same element.
Both these approaches will not verify if it is two objects which have the same content, but are different objects. i.e. {foo: "bar"} !== {foo: "bar"}
I have a array of string.
let arr=["robin","rohit","roy"];
Need to find all the common character present in all the strings in array.
Output Eg: r,o
I have tried to create a function for above case with multiple loops but i want to know what should be the efficient way to achive it.
Here's a functional solution which will work with an array of any iterable value (not just strings), and uses object identity comparison for value equality:
function findCommon (iterA, iterB) {
const common = new Set();
const uniqueB = new Set(iterB);
for (const value of iterA) if (uniqueB.has(value)) common.add(value);
return common;
}
function findAllCommon (arrayOfIter) {
if (arrayOfIter.length === 0) return [];
let common = new Set(arrayOfIter[0]);
for (let i = 1; i < arrayOfIter.length; i += 1) {
common = findCommon(common, arrayOfIter[i]);
}
return [...common];
}
const arr = ['robin', 'rohit', 'roy'];
const result = findAllCommon(arr);
console.log(result);
const arr = ["roooooobin","rohit","roy"];
const commonChars = (arr) => {
const charsCount = arr.reduce((sum, word) => {
const wordChars = word.split('').reduce((ws, c) => {
ws[c] = 1;
return ws;
}, {});
Object.keys(wordChars).forEach((c) => {
sum[c] = (sum[c] || 0) + 1;
});
return sum;
}, {});
return Object.keys(charsCount).filter(key => charsCount[key] === arr.length);
}
console.log(commonChars(arr));
Okay, the idea is to count the amount of times each letter occurs but only counting 1 letter per string
let arr=["robin","rohit","roy"];
function commonLetter(array){
var count={} //object used for counting letters total
for(let i=0;i<array.length;i++){
//looping through the array
const cache={} //same letters only counted once here
for(let j=0;j<array[i].length;j++){
//looping through the string
let letter=array[i][j]
if(cache[letter]!==true){
//if letter not yet counted in this string
cache[letter]=true //well now it is counted in this string
count[letter]=(count[letter]||0)+1
//I don't say count[letter]++ because count[letter] may not be defined yet, hence (count[letter]||0)
}
}
}
return Object.keys(count)
.filter(letter=>count[letter]===array.length)
.join(',')
}
//usage
console.log(commonLetter(arr))
No matter which way you choose, you will still need to count all characters, you cannot get around O(n*2) as far as I know.
arr=["robin","rohit","roy"];
let commonChars = sumCommonCharacters(arr);
function sumCommonCharacters(arr) {
data = {};
for(let i = 0; i < arr.length; i++) {
for(let char in arr[i]) {
let key = arr[i][char];
data[key] = (data[key] != null) ? data[key]+1 : 1;
}
}
return data;
}
console.log(commonChars);
Here is a 1 liner if anyone interested
new Set(arr.map(d => [...d]).flat(Infinity).reduce((ac,d) => {(new RegExp(`(?:.*${d}.*){${arr.length}}`)).test(arr) && ac.push(d); return ac},[])) //{r,o}
You can use an object to check for the occurrences of each character. loop on the words in the array, then loop on the chars of each word.
let arr = ["robin","rohit","roy"];
const restWords = arr.slice(1);
const result = arr[0].split('').filter(char =>
restWords.every(word => word.includes(char)))
const uniqueChars = Array.from(new Set(result));
console.log(uniqueChars);
I am trying to add an object to an array if the array already does not have that object.
So I have an array as follows
[{id:1},{id:2},{id:3}]
I want to check if a id:1 exist or not if not then add if yes then show an error or log a message.
I am able to achieve this using a simple array as follows.
let result =[1,2,2,3,1,4,1,4,2,3].filter((el, i, a) => i === a.indexOf(el));
I cannot figure out how to achive the same with array of objects.
Thanks
You can use some to check for duplicates like:
// array with duplicate objects {id:1}
let arr = [{id:1},{id:1},{id:2}]
function duplicateFound(arr){
const ids = arr.map(x => x.id);
return ids.some((item, idx) => ids.indexOf(item) != idx);
}
console.log(duplicateFound(arr));
// array with not duplicates
arr = [{id:1},{id:2},{id:3}]
console.log(duplicateFound(arr));
You can use Array#filter, and check the length:
const arr = [{id:1},{id:2},{id:3}];
const el = { id: 1 };
const exists = arr.filter(({ id }) => id === el.id).length > 0;
console.log(exists);
Or you can use Array#find, which has a slight advantage over Array#filter, since it will stop as soon as an item was found.
const arr = [{id:1},{id:2},{id:3}];
const el = { id: 1 };
const exists = !!arr.find(({ id }) => id === el.id);
console.log(exists);
You can wrap your array with a proxy that has a set trap, to prevent the insertion of duplicates automatically:
const arr = [{id:1},{id:2},{id:3}];
const arrayChangeHandler = {
set: function(target, property, value, receiver) {
if(property === 'length') {
return true;
}
const exists = !!target.find(({ id }) => id === value.id);
if(exists) {
console.log(`Id: ${value.id} exists!`); // you can return false here, and it will throw an error
} else {
target.push(value);
}
return true;
}
};
const pArr = new Proxy(arr, arrayChangeHandler);
pArr.push({ id: 1 });
pArr.push({ id: 10 });
console.log(JSON.stringify(arr));
You could try inserting all values as keys to a new array then flip keys & vals
let arr = "abccba".split('');
let res = [];
arr.forEach((n) => {
res[n] = n;
});
console.log(Object.keys(res));
A concern might be that if your values are numbers then you might need to recast them eg.
res = res.map(n) => +n
This javascript code tries to use the array.filter for better performance instead of the for loop "I guess". Any way, the results are not the same, when it was expected to be.
It tries to find out the names of students who are included in the searchWords array.
Any ideas why?thx
let searchWords = ['john','matt','marry'];
let students = ['matt','jack'];
let names = [];
for (let i = 0; i < searchWords.length; i++) {
if (students.indexOf(searchWords[i]) !== -1) {
names.push(searchWords[i]);
}
}
console.log(names.length); // => 1 "correct"
names = [];
names = searchWords.filter(x => students.filter(y => students.indexOf(x) !== -1));
console.log(names.length); // => 3 "incorrect"
The filter line has essentially added another loop. It should be
names = searchWords.filter(x => students.indexOf(x) !== -1);
What is the best way to search a particular parameter of an object array in Angular?
I populate my array from an Angular foreach :
$scope.arrayiwanttosearch = [];
angular.forEach(data, function(value, key) {
try{
var arrstring = new Array();
arrstring = value.img.split(',');
obj.name = value.name;
obj.selectedcolor = arrstring[0];
obj.colors = value.img;
obj.ischanging = false;
$scope.arrayiwanttosearch.push(obj);
}
catch(ex){
}
})
I can only use array.index of when its an array without objects, is there a way to do this without using a for loop? Im trying to find the index of the object that has the obj.name == "test"
Im trying to find the index of the object that has the obj.name ==
"test"
This is a straight use of findIndex.
var arrayiwanttosearch = [
{
name : "nottest"
},
{
name : "test"
}
];
var index = arrayiwanttosearch.findIndex(obj => obj.name === "test");
console.log(index);
You can use the native javascript 'filter' which will bring back all the matching members of the array, or 'find' which brings back the first one it finds, or 'findIndex';
// This finds the first matching array element with an object property === 2
$scope.arr = [{a:2,b:3}, {a:2,b:4}];
$scope.result = $scope.arr.find((item) => item.a === 2);
// The filter does the same but brings back all matching elements;
$scope.arr = [{a:2,b:3}, {a:2,b:4}];
$scope.result = $scope.arr.filter((item) => item.a === 2);
// The index result;
$scope.arr = [{a:2,b:3}, {a:2,b:4}];
$scope.result = $scope.arr.findIndex((item) => item.a === 2);
ES6 JS notation, but easy to adapt for ES5 JS.
You can use Array.prototype to get the index value in an array of objects.
var index = $scope.arrayiwanttosearch.indexOfname("test");
Array.prototype.indexOfname = function(name) {
for (var i = 0; i < this.length; i++)
if (this[i].name === name)
return i;
return -1;
}