I have an array that can't be changed in terms of the element positions:
var array = ['item1', 'section1', 'section2', 'section3', 'section4', 'section5', 'prod1', 'prod2']
I want to make a new array from 'array' that takes the elements from position 1 - 5 (so all the section elements). It needs to be by position as the section elements make change by name.
var array2=array.slice(1,6)
See here for more information.
let's say we have an array like this
const FILES_WITH_10_ASSETS = [
'../assets/uploads/Desktop-300x600.jpeg',
'../assets/uploads/Desktop-728x90.png',
'../assets/uploads/Mobile-160x600.jpeg',
'../assets/uploads/Mobile-300X50.jpeg',
'../assets/uploads/Mobile-320x50.jpeg',
'../assets/uploads/Mobile-320x480.jpeg',
'../assets/uploads/Mobile-1024x768.jpeg',
'../assets/uploads/Tablet-300x250.jpeg',
'../assets/uploads/Tablet-Interstitial-320x480.gif',
'../assets/uploads/Tablet-Interstitial-320x480.jpeg'
];
now we want some specific items from an array, we will create a function for this, here I have stored the function in an constant for further use
const SELECT_ASSETS = function(assetName: string) {
let filtered_assets: string[] = [];
for (let i in FILES_WITH_10_ASSETS) {
if (FILES_WITH_10_ASSETS[i].includes(assetName) === true) {
filtered_assets.push(FILES_WITH_10_ASSETS[i]);
}
}
return filtered_assets;
};
and we call the method like this in our file
const ASSETS_NAME = SELECT_ASSETS(ASSET_NAME);
now we can pass the assets name to any function or method, if we pass the ASSET_NAME as Tablet we will get all three tablet paths, or if we change it to Mobile, we will get all five Mobile paths
Related
I' am a begginer with Javascript and I am currently try to find all possible paths of a returned JSON object from an axios GET request.Every item can belong to one or more groups, and one group can belong to an other group.
e.g.
{
"name": "item1",
"groupNames": [ "GROUPA" ]
}
{
"name": "GROUPA",
"groupNames": [
"GROUPB"
]
}
....
{
name: "GROUPZ"
"groupNames": [
]
}
My issue is that my code is working only if a item name has only one parent groupName in the array.
What if we have more than one parentgroupNames? e.g
{
"name": "item1",
"groupNames": [ "GROUPA","GROUC",GROUBD ]
}
...
My current code:
let parent = 'item1';
do{
let endpoint = ${process.env.OPENHAB_HOST}:${process.env.OPENHAB_PORT}/rest/items/${parent}?recursive=false
result = await getAxiosRequest(endpoint,{},res); // get request to specific endpoint
parent = result.data.groupNames; }
while(result.data.groupNames.length !== 0 )
To find all the parent groups for an item that has multiple parent groups, you can modify your code as follows:
Initialize an array called parents to store the parent groups that you find.
In the loop, instead of assigning parent to result.data.groupNames, iterate over result.data.groupNames and add each group to the parents array.
After the loop, parents will contain all the parent groups for the given item.
Here's how the modified code would look:
let parent = 'item1';
let parents = []; // initialize array to store parent groups
do {
let endpoint = `${process.env.OPENHAB_HOST}:${process.env.OPENHAB_PORT}/rest/items/${parent}?recursive=false`;
result = await getAxiosRequest(endpoint,{},res); // get request to specific endpoint
result.data.groupNames.forEach(group => parents.push(group)); // add each group to the parents array
parent = result.data.groupNames;
} while(result.data.groupNames.length !== 0);
console.log(parents); // array of parent groups
This should work even if the item has multiple parent groups.
It is not entirely clear what the end result should be after the loop has ran, but I'll assume you would maybe collect the paths from the given item in an array.
As indeed you can get multiple groups, you need to either store them in a queue/stack for later processing, or use recursion (for the same reason).
Here is how it could look with recursion:
function async visit(parent) {
const endpoint = `${process.env.OPENHAB_HOST}:${process.env.OPENHAB_PORT}/rest/items/${parent}?recursive=false`;
const {data} = await getAxiosRequest(endpoint, {}, res);
const results = [];
for (const group of data.groupNames) {
results.push(...(await visit(group)).map(path => path.concat(group)));
}
return results;
}
visit('item1').then(paths => {
// ....
});
The name list is supposedly as below:
Rose : 35621548
Jack : 32658495
Lita : 63259547
Seth : 27956431
Cathy: 75821456
Given you have a variable as StudentCode that contains the list above (I think const will do! Like:
const StudentCode = {
[Jack]: [32658495],
[Rose]: [35621548],
[Lita]: [63259547],
[Seth]: [27956431],
[Cathy]:[75821456],
};
)
So here are the questions:
1st: Ho can I define them in URL below:
https://www.mylist.com/student=?StudentCode
So the link for example for Jack will be:
https://www.mylist.com/student=?32658495
The URL is imaginary. Don't click on it please.
2nd: By the way the overall list is above 800 people and I'm planning to save an external .js file to be called within the current code. So tell me about that too. Thanks a million
Given
const StudentCode = {
"Jack": "32658495",
"Rose": "35621548",
"Lita": "63259547",
"Seth": "27956431",
"Cathy": "75821456",
};
You can construct urls like:
const urls = Object.values(StudentCode).map((c) => `https://www.mylist.com?student=${c}`)
// urls: ['https://www.mylist.com?student=32658495', 'https://www.mylist.com?student=35621548', 'https://www.mylist.com?student=63259547', 'https://www.mylist.com?student=27956431', 'https://www.mylist.com?student=75821456']
To get the url for a specific student simply do:
const url = `https://www.mylist.com?student=${StudentCode["Jack"]}`
// url: 'https://www.mylist.com?student=32658495'
Not sure I understand your second question - 800 is a rather low number so will not be any performance issues with it if that is what you are asking?
The properties of the object (after the trailing comma is removed) can be looped through using a for-in loop, (see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in)
This gives references to each key of the array and the value held in that key can be referenced using objectName[key], Thus you will loop through your object using something like:
for (key in StudentCode) {
keyString = key; // e.g = "Jack"
keyValue = StudentCode[key]; // e.g. = 32658495
// build the urls and links
}
to build the urls, string template literals will simplify the process (see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) allowing you to substitute values in your string. e.g.:
url = `https://www.mylist.com/student=?${StudentCode[key]`}
Note the use of back ticks and ${} for the substitutions.
Lastly, to build active links, create an element and sets its innerHTML property to markup built using further string template literals:
let link = `<a href=${url}>${keyValue}</a>`
These steps are combined in the working snippet here:
const StudentCode = {
Jack: 32658495,
Rose: 35621548,
Lita: 63259547,
Seth: 27956431,
Cathy: 75821456,
};
const studentLinks = [];
for (key in StudentCode) {
let url = `https://www.mylist.com/student=?${StudentCode[key]}`;
console.log(url);
studentLinks.push(`<a href href="url">${key}</a>`)
}
let output= document.createElement('div');
output.innerHTML = studentLinks.join("<br>");
document.body.appendChild(output);
I am looping through a collection of blog posts to firstly push the username and ID of the blog author to a new array of arrays, and then secondly, count the number of blogs from each author. The code below achieves this; however, in the new array, the username and author ID are no longer separate items in the array, but seem to be concatenated into a single string. I need to retain them as separate items as I need to use both separately; how can I amend the result to achieve this?
var countAuthors = [];
blogAuthors = await Blog.find().populate('authors');
blogAuthors.forEach(function(blogAuthor){
countAuthors.push([blogAuthor.author.username, blogAuthor.author.id]);
})
console.log(countAuthors);
// Outputs as separate array items, as expected:
// [ 'author1', 5d7eed028c298b424b3fb5f1 ],
// [ 'author2', 5dd8aa254d74b30017dbfdd3 ],
var result = {};
countAuthors.forEach(function(x) {
result[x] = (result[x] || 0) + 1;
});
console.log(result);
// Username and author ID become a single string and cannot be accessed as separate array items
// 'author1,5d7eed028c298b424b3fb5f1': 15,
// 'author2,5dd8aa254d74b30017dbfdd3': 2,
Update:
Maybe I can explain a bit further WHY on what to do this. What I am aiming for is a table which displays the blog author's name alongside the number of blogs they have written. However, I also want the author name to link to their profile page, which requires the blogAuthor.author.id to do so. Hence, I need to still be able to access the author username and ID separately after executing the count. Thanks
You could use String.split().
For example:
let result = 'author1,5d7eed028c298b424b3fb5f1'.split(',')
would set result to:
['author1' , '5d7eed028c298b424b3fb5f1']
You can then access them individually like:
result[1] //'5d7eed028c298b424b3fb5f1'
Your issue is that you weren't splitting the x up in the foreach callback, and so the whole array was being converted to a string and being used as the key when inserting into the results object.
You can use array destructuring to split the author name and blog id, and use them to optionally adding a new entry to the result object, and then update that result.
countAuthors = [
['author1', 'bookId1'],
['author2', 'bookId2'],
['author1', 'bookId3'],
['author1', 'bookId4'],
['author2', 'bookId5']
]
var result = {};
countAuthors.forEach(([author, id]) => {
if (result[author] === undefined) {
result[author] = {count: 0, blogIds: []};
}
result[author].count += 1;
result[author].blogIds.push(id);
});
console.log(result);
I have 2 Arrays and one is 2 dimensional and another is 1 dimensional. I need to compare both and need to store there common data in another array. I tried the below approach:-
tw.local.listtodisplayNW = new tw.object.listOf.listtodisplayNWBO();
//if(tw.local.SQLResults[0].rows.listLength >
// tw.local.virtualServers.listLength)
var k=0;
for (var i=0;i<tw.local.SQLResults[0].rows.listLength;i++)
{
log.info("Inside SQLResults loop - For RuntimeID: "
+tw.local.SQLResults[0].rows[i].data[3]);
for(var j=0;j<tw.local.virtualServers.listLength;j++)
{
log.info("Inside API loop - For RuntimeID: "
+tw.local.virtualServers[j].runtimeid);
if(tw.local.SQLResults[0].rows[i].data[3] ==
tw.local.virtualServers[j].runtimeid)
{
tw.local.listtodisplayNW[k] = new tw.object.listtodisplayNWBO();
tw.local.listtodisplayNW[k].vsysName =
tw.local.virtualServers[j].virtualSystemName;
tw.local.listtodisplayNW[k].vsysID =
tw.local.virtualServers[j].virtualSystemId;
tw.local.listtodisplayNW[k].serverName =
tw.local.virtualServers[j].serverName;
tw.local.listtodisplayNW[k].serverID =
tw.local.virtualServers[j].serverId;
tw.local.listtodisplayNW[k].runtimeID =
tw.local.virtualServers[j].runtimeid;
//tw.local.listtodisplayNW[k].IPAddress =
tw.local.virtualServers[j].nics[j].ipAddress;
log.info("VsysName:
"+tw.local.listtodisplayNW[k].vsysName+"RuntimeID:
"+tw.local.listtodisplayNW[k].runtimeID);
//tw.local.listtodisplayNW[k] = new
tw.object.listtodisplayNWBO();
tw.local.listtodisplayNW[k].currentSpeed =
tw.local.SQLResults[0].rows[i].data[5];
log.info("VsysName:
"+tw.local.listtodisplayNW[k].vsysName+"RuntimeID:
"+tw.local.listtodisplayNW[k].runtimeID+"CurrentSpeed:
"+tw.local.listtodisplayNW[k].currentSpeed);
if(tw.local.listtodisplayNW[k].currentSpeed != "100 Mbps")
{
tw.local.listtodisplayNW[k].desiredSpeed = "100 Mbps";
}
else
{
tw.local.listtodisplayNW[k].desiredSpeed = "1 Gbps";
}
log.info("DesiredSpeed:
"+tw.local.listtodisplayNW[k].desiredSpeed);
k++;
}
}
log.info("Length of
listtodisplayNW"+tw.local.listtodisplayNW.listLength);
}
In above code SQLResults is a 2-d array and virtualServers is a 1-D array.
I need to compare both these array and common data need to be store in another array. Here performance is not good. Is there any other way to do this efficiently. Please make a needful favour and Thanks in advance.
Assuming integer data, the following example works on the theme of array implementation of set intersection, which will take care of performance.
Convert 2D array to 1D.
var 2DtoIDArray = 2DArray.join().split(",");
Create an array named marker whose purpose is to serve as a lookup that element.
This needs to be done as follows.
Iterate through the smaller array, say 1DArray and keep setting marker as follows throughout iteration.
marker[1DArray[counter]]='S1';
Now iterate through 2Dto1DArray array(you may use nested loop iteration if you dont want to convert it to 1 dimesnional) and for each element
of this array check if its marked as 'S1' in the marker lookup array.
If yes, keep adding the elements in the commonElementsArray.
Follow this simple approach
Since the matching condition is only one between the two large arrays, create two maps (one for each array) to map each record against that attribute which is to be matched
For SQLResults
var map1 = {};
tw.local.SQLResults[0].rows.each( function(row){
map1[ row.data[3] ] = row;
});
and similarly for virtual servers
var map2 = {};
tw.local.virtualServers.each( function(vs){
map2[ vs.runtimeid ] = vs;
});
Now iterate these two maps wrt to their keys and set the values in new array
new array being tw.local.listtodisplayNW
tw.local.listtodisplayNW = [];
Object.keys( map1 ).forEach( function( key ){
if( map2[ key ] )
{
//set the values in tw.local.listtodisplayNW
}
})
Complexity of the approach is simply O(n) since there is no nested loops.
i have a javascript code below.
bgCustom = { 'items':[], 'items_num':3, 'element':'#bg_custom_thumbs', 'next': '#bg_custom_next_thumb', 'prev': '#bg_custom_prev_thumb', 'width':165 };
//populate array
bgCustom.items = [["images/backgrounds/bear-ears_thumb.jpg", "bear-ears.jpg", "Bear-Hair"], ["images/backgrounds/blue-swirls_thumb.jpg", "blue-swirls.jpg", "WaterSmoke"]];
ho do i create bgCustom.items array dynamic. means i want a array list
[['val1_1','val1_2','val1_3'],['val2_1','val2_2','val2_3']]
Can any body help me.
You can add arrays to the end of the array:
bgCustomer.items.push(['val1_1','val1_2','val1_3']);
bgCustomer.items.push(['val2_1','val2_2','val2_3']);
You can also assign arrays at specific indexes. The array will automatically expand if you use an index outside the current size:
bgCustomer.items[0] = ['val1_1','val1_2','val1_3'];
bgCustomer.items[1] = ['val2_1','val2_2','val2_3'];
bgCustom = { 'items':[], 'items_num':3, 'element':'#bg_custom_thumbs', 'next': '#bg_custom_next_thumb', 'prev': '#bg_custom_prev_thumb', 'width':165 };
function PushToItems(a,b,c) {
var ar = [a,b,c];
bgCustom.items.push(ar);
}
PushToItems("images/backgrounds/bear-ears_thumb.jpg", "bear-ears.jpg", "Bear-Hair");
That should work for making it a little more dynamic.