Array of arrays of Objects - javascript

I have an array that looks like this.
let name
function arrayfunction () {
selling = confirmedSale
testSample = {something:das, something1: dso}
productName = [name, selling ,testSample]
qualifiedProduct = ["Selling", productName]
qualified.push(qualifiedProduct);
}
I want to be able to search by name and do work on that name. However, the challenge I am encountering is that it's a nested array of arrays with an object. I have figured out how to do work on the object via two foreach loops but am unable to delete productName and all related elements when the work is complete.
console logging qualified through each of my sets of creating the array to buying and selling is working great and works as it should. Now, I want to delete the productName and all associated elements to productName from the array of Buying and Selling once I have finished doing work on it.
I am relatively new to programming and any direction would be appreciated!

Use findIndex() to find the index of the product with the name you want to remove.
index = qualified.findIndex(q => q[0] == "Selling" && q[1][0] == "someName");
if (index != -1) {
qualified.splice(index, 1);
}

Related

Compare two arrays values, and populate if no match

I need help with matching two arrays. I have TypeScript in the example code, but it can be understood since its about array operations more or less.
In short:
I have two arrays; myItems[] and allItems[]. myItems[] can only hold maximum 4 values.
I want to first check if the items in myItems[] is 4, AND/OR exist in the other array allItems[].
If NOT: populate myItems[] with values from allItems[] (until it contains 4 values) and/or replace the items that is missing (relative to allItems[]) with other items in allItems[] (I'm trying to use default values instead of randomly taking values in my example code).
Description:
I have a widgets (quick links) module that show 4 links at a time, but there are in total 20 different links (or more). All links is stored in a list and each has its own unique ID. In code, all links is extracted and returned in an array (like the allItems[] in above example).
The user can save the links he/she wants to show in the widget. The user settings is stored and returned as an array with the ID of the links that the user have saved. Like the myItems[] above,
Problem:
I have a solution that check the length of the myItems[], and if needed populates items from the allItems[] one. However, it does NOT check if the items in the user array exist in allItems[] and then populates it with the default links. In practical it means that the user can save links and it will be shown in the widget as intended. BUT if a link is removed in the list (which will then be removed in the allItems array) only 3 items will be shown as the myItems[] doesn't check with the allItems[] array to see if it exists there.
Code:
public async getUserWidgets(): Promise<Widget[]> {
let allWidgets = await this.getAllWidgets(); //Array with all the links ID from the list
let userRepository = new UserProfileRepository(this.absoluteWebUrl);
let userSettings = await
userRepository.getUserExtensionValues(this.context); //Extracting the user Settings which contains the ID of the saved linksvar
result:Widget[] = []; //the array where the result will go in
//if the user doesnt have any saved links, or if the user have less than 4 saved links
if (userSettings == null || userSettings.QuickLinksWidgets == null ||
userSettings.QuickLinksWidgets.length < 4)
{result = allWidgets.filter((w) => {return w.defaultWidget;}).slice(0,4);
}
else {var ids =userSettings.QuickLinksWidgets;
for (let i = 0; i < 4; i++) {
let id = '' + ids[i];let w = allWidgets.filter((e) => { return e.id == id;});
if (w.length == 0) {
continue;}
result.push(w[0]);}}
return new Promise<Widget[]>(async (resolve) => {resolve(result);});}
A simple way to check if an array holds a value is using the includes() method.
for(let value of myitems){
if(allitems.includes(value)){
console.log("Duplicate")
}
}
The above code will loop through each value in your myitems array and test if that value is in the allitems array.

Array filter method to match IDs and check properties exist

I'm currently using a method to try to filter some arrays, the method is almost working but I can't seem to access the exact values -
I make a call and add each returned array into a bigger array, these arrays will then be assigned a productId and maybe some data, i am appending the productIds using this:
data.push({'productId': product.id});
Which unfortunately adds a new object to the array which means my function below doesnt work unless the productId is in the first object of each array:
let matchedArray = data.flatMap(arr => arr.filter(obj => obj.productId == id))
What I need to do is filter the array down to the subarray that matches the productId and ID and also that has some of the fields of data such as 'name' - so it checks that the name isnt empty.
The data set looks like this (array of subarrays)
id = 12345
data = [[],[],[],[],[],[],[],[],[{"id":"123","name":"africa soul
2019","startDate":null,"endDate":null,"country":null,"city":null,"type":"Ev
ent","members":null},{"productId":"12345"}],[],[],[],[],[],[],
[],[],[],[],[]]
As you can see the productId is appended to the array but isnt now working with my filter method, i need to filter for the right array that has matching ID's and at least one of the fields are also existing. I either need to change the way the productId is manually appended, or change the filter method?
Thanks so much if you can help
If you want to filter all the arrays which have some object which have a productId equal to a given value:
let data = [[],[],[],[],[],[],[],[],[{"id":"123","name":"africa soul 2019","startDate":null,"endDate":null,"country":null,"city":null,"type":"Event","members":null},{"productId":"12345"}],[],[],[],[],[],[],[],[],[],[],[]],
id = "12345";
let filtered = data.filter(arr => arr.some(a => a.productId === id))
console.log(filtered)
If you want to get the first match, use find instead of filter

filter an array based on multiple arrays using some()

It's quite possible I am going about this the wrong way, but I have a primary array that i need to filter if any of it's objects values exist in two other arrays. I am trying to use a combination of filter() and some() but what I have right now is not working.
const milestones = <FormArray>this.piForm.get('_milestones');
if (this.piById) {
milestonesToCreate = milestones.value
.filter(milestone => !this.piById.milestones.some(item => item.milestoneId === milestone.milestoneId));
milestonesToDelete = this.piById.milestones
.filter(milestone => !milestones.value.some(item => item.milestoneId === milestone.milestoneId));
milestonesToUpdate = milestones.value
.filter(milestone => milestones.value
.some(item =>
item.milestoneId === milestonesToCreate.milestoneId && milestonesToDelete.milestoneId));
}
In the code above milestonesToUpdate should be a the filtered results where the array consists of objects that are not in milestonesToCreate and milestonesToDelete
Hopefully I've explained this well enough.
ADDED SAMPLE MILESTONES ARRAY
milestones = [
{
"milestoneId": 0
}
]
Firstly, it looks like your problem is just a misunderstanding of boolean checks in your final call to some().
You have put:
item.milestoneId === milestonesToCreate.milestoneId && milestonesToDelete.milestoneId
Which is the same as saying, where item.milestoneId equals milestonesToCreate.milestoneId AND milestonesToDelete.milestoneId exists. I expect that you are just trying to check if the current value exists in both arrays.
it's better to achieve that in single pass:
put all elements to elementsToUpdate, copy all elements from your this into elementsToDelete
iterate through elementsToUpdate, once some item does not exist in another list, move that element into elementsToCreate
if element exists in both, remove it from elementsToDelete.
finally you will get 3 lists you need.
And you can even speed up code more if instead of using arrays you use hash(old good {}) where id are used as keys. Then check "if element is here" would be as easy as item in elementsToUpdate instead of iterating all the elements each time

Looping through a List of objects in JavaScript

I want to loop through the student list which I received from a REST service located on a server. this list contains objects for students enrolled in a section. Each object has firstName, lastName, student ID and many other attributes, specifically an attribute called isAbsent. Its a Boolean value where it has true if the student is absent and false if the student is present in not absent. I want to store the students IDs who are absent (have isAbsent=true) in another String Array.
I tried this :
{
//this array will store the IDs of students who are absent.
$scope.selection = [];
//$scope.studentList is the list of students for CRN=X and Date=Y
for (id in $scope.studentList) {
if ($scope.studentList.isAbsent === true) {
$scope.selection.push($scope.studentList.id);
console.log($scope.selection);
}
}
}
This code doesn't execute. I have no clue why, I guess the problem in the loop structure. Any help?
Maybe this will help?
for (var i=0;i<$scope.studentList.length;i++)
{
if ($scope.studentList[i].isAbsent === true)
{
$scope.selection.push($scope.studentList[i].id);
console.log($scope.selection);
}
}
p.s. don't use for..in with arrays. It will display an index instead of a value. It's not like C#.
Depending on what browsers you need to support (e.g. IE >= 9), I'd suggest the newer foreach construct. I find it easier to use:
$scope.studentList.forEach(function(value, index, array) {
if (value.isAbsent === true)
{
$scope.selection.push(value.id);
console.log($scope.selection);
}
});

Checking for equivelance

OK, I'm missing something here and I just can't seem to find it because the logic seems correct to me, but I'm certain I'm not seeing the error.
var VisibleMarkers = function() {
var filtered = _.reject(Gmaps.map.markers, function(marker) {
return marker.grade != $('.mapDataGrade').val() && !_.contains(marker.subjects,$('.mapDataSubjects').val())
});
return filtered
}
I'm using underscore.js and jQuery to simplify my javascript work.
So right now, I'm checking by means of selects which data gets to be rejected and then I display the filtered markers on the (google) map (if it helps at all, this is using gmaps4rails which is working perfectly fine, its this bit of javascript that's making me lose the last of the hairs on my head).
Currently, the code functions 100% correctly for the ".mapDataGrade" select, but the ".mapDataSubjects" isn't. Now the markers object has a json array of the subjects (this is for students) and each item in the array has its ID. Its this ID that I am supposed to be checking.
Can someone see what I'm doing wrong?
If there's more info that needs to be included, please let me know.
This is on plain javascript on a RoR application using gmaps4rails
Now the markers object has a json array of the subjects (this is for students) and each item in the array has its ID. Its this ID that I am supposed to be checking.
_.contains compares a values, but it sounds like you want your iterator to compare a value to an object's "id" property. For that, _.some would work; it's like contains, except that, instead of comparing values, you can write the comparison as a function:
Returns true if any of the values in the list pass the iterator truth test.
Here's how you'd use it:
!_.some(marker.subjects, function(subject) {
return subject.id == $('.mapDataSubjects').val();
})
If I'm right, the whole line should be like this:
return marker.grade != $('.mapDataGrade').val() &&
// check that none of the subjects is a match
!_.some(marker.subjects, function(subject) {
// the current subject is a match if its ID matches the selected value
return subject.id == $('.mapDataSubjects').val();
});

Categories