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.
Related
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);
}
I'm trying to do something which I thought would be extremely simple but is baffling me for some reason: I've got a function that's pushing a bunch of IDs of locations into an array and I don't want it to push these values in if they're null (the script allows user input from a Google Sheet so it's possible they'll input an incorrect value that won't get matched to an ID).
I've tried this so far:
for (var i = 0; i <= startEndDifference; i++) {
if (objectLocationInputStart != null) {
objectLocationIdsArray.push(locationMatch(objectLocationInputStart));
}
objectLocationInputStart = objectLocationInputStart + 1
}
but null values are still pushing to the array.
For context, this is referring to two cells in a Google sheet with a starting number and an ending number, and the for loop picks up all the numbers in between and matches them to an ID using the function. Everything it does is working perfectly other than passing in the null values.
I have the following code which should filter one dynamic array (up to 300 thousands elements) from all elements not contained in another constant array:
orders[] // is already filled with data
let materials = [] // create empty array
for (let scheme in schemes) { // loop constant object
materials.push(schemes[scheme].typeID) // take id and add it to materials array
}
materials = Array.from(new Set(materials)) // filter out duplicates
console.log(materials) // everything looks fine here, 83 unique ids
for (let order in orders) { // now loop the main array
if (!materials.includes(orders[order].type_id)) { // if order's containment id is not found in materials array
orders.splice(order,1) // remove it from array
order -= 1 // and one step back to compensate removed index (do I need it or is it processed normally even after .splice?)
}
}
// and send filtered orders into browser when certain url is requested
However not all unnecessaty records are filtered out, there are lots and lots of them whose id cannot be found in materials array.
What is my mistake and where is error?
for (let scheme in schemes)
Thats how you iterate over keys in an object. Rather iterate over the entries in an array:
for (let scheme of schemes)
Additionally you should consider using the Set for lookup as its much faster. And map and filter might be useful:
const materials = new Set(schemes.map(scheme => scheme.typeID));
orders = orders.filter(el => materials.has(el.type_id));
I have a json array that looks like:
var ad =[{"itemID":"195","issue":"first","buttonText":"First","date":1481200571","link":"https://example.com/link"},{"itemID":"197","issue":"other","buttonText":"Something Else","date":1481200571","link":"https://example.com/linkother"},{"itemID":"215","issue":"main","buttonText":"Important","date":1481200571","link":"https://example.com/linkmain"}];
(The above example has 3 objects, but in reality it could have many more.)
And I have an ajax action on my page that will delete the row from the db that one of these objects represents. Rather than refresh my page with the entire json which is many rows and a db call, I would like to just permanently remove the object that is represented by itemID from the array in my page using javascript.
There are many ways of doing it.
The ones that come to my mind:
filtering out an item:
ad = ad.filter(item => item.itemId != 'DELETED ID');
finding index of an item and removing it
var deletedItem = ad.find(item => item.itemId == 'DELETED ID');
ad.splice(ad.indexOf(deletedItem), 1);
I have a select form element and it accepts multiple items.
When the form is submitted I'm adding the items into an array to then handle them then running through the array to perform an action on each item.
I'm coming across a problem when only one item is selected.
The length of the array when one item is passed through is not 1 it's the number of characters in the item that is selected.
function processForm(formObject){
var list = [];
list = formObject.listElement;
for (var i=0;i<list.length;i++) {
Logger.log(list[i]);
}
}
The above would log each item if more than one item is selected in the form. If only one is selected the length is the number of character in that one item. How can I resolve this so if only one item is selected we treat this as an array with one item?
You have:
var list = [];
which assigns an empty array to list, then:
list = formObject.listElement
replaces it with whatever is returned by formObject.listElement, so the initial assignment is pointless.
You haven't indicated what type of control listElement is, it may be a Class MultipleChoiceItem or Class ListItem. Both have a getChoices method that returns an array of the choices.
If you use that method, there should be no need to test whether the return value is an array or not, it should always be a (possibly empty) array:
list = formObject.listElement.getChoices();
assuming that listElement is one of the above objects.
Iterating through a string as if it were an array would give the behavior you describe. You can convert an array first, if it's not already one
var list = formObject.listElement;
if (!Array.isArray(list)) list = [list];