I have an array of ints called SelectedItems. I have another array that contains objects that's called AvailableItems and that was parsed from json; these Item objects have the properties {ContainerID, ContainerName, ItemID, ItemName}.
I want to convert SelectedItems from an array of ints to an array of Items where each ItemID is replaced with the Item object that corresponds to the ItemID in AvailableItems. Each ItemID in SelectedItems is unique.
I started with 2 loops: one that loops through each element of SelectedItems but then I find myself looping through AvailableItems each time to find the corresponding ItemID with the object keys I need to copy into SelectedItems.
So basically I built a seemingly very inefficient loop. I was wondering if there was a better way to do it by avoiding a repeated loop inside a loop?
Sample data:
For AvailableItems, you have
{
ContainerID: i,
ContainerName: 'SomeName',
ItemID: j,
ItemName: 'SomeOtherName'
}
with may be 1,000 objects and then SelectedItems is array of ints
[23,43,64,34...]
Thanks.
You could put each object in the numeric array AvailableItems at the index that matches its ItemID.
So you know that the item with an ItemID of 5 is at AvailableItems[5] instead of having to loop through and find it.
Not sure what effect this will have if you have big gaps between different ItemID values, but you can try it and see if it works well.
UPDATE:
After a quick search, and reading this answer, it looks like having gaps between your indexes will not waste a bunch of memory. However, it will affect the result of checking AvailableItems.length. If you have an array with one entry, but the index of that entry is 500, then AvailableItems.length will return 501, even though there is only one entry in the array.
As long as you don't need to use the length function, this solution should work for you.
If you are able to get any arbitrary AvailableItem without looping through the whole array by just addressing it by its ID(if you have an index-based array where IDs are indexes) then you can go through the SelectedItems and check if it exists in AvailableItems, and if it does then you convert the SelecteItem into an object and add it to some temporary array for later use.
Related
I'm trying to setup a 2-d array, which should receive values at specific sub-arrays. I created my array with:
myArray= Array(100).fill([])
Now, let's say I want to push a value to say sub-array number 40
I'm doing this like that:
myArray[40].push("myValue")
I would expect the value to be pushed only to the myArray[40] instead it is pushed as the first element of every of the hundred sub-arrays.
I searched for the solution for quite some time, but I still have no idea what I'm doing wrong. Please help.
fill will push the same value to each element, not a copy of it. That's fine when it's a number or string or something else immutable. But now each copy is a reference to the same object.
There are a number of ways to fix this. Here's one (switched to ten elements for demonstration):
const myArray = [...Array(10)].map((_, i) => [])
myArray[4].push('myValue')
console.log(myArray)
I have a React application which handles rooms and their statistics.
Previously, I had the code set up to pass as props to the next component:
the raw statistics (not a concern for the question)
an array of all the rooms set up as follows
I figured it would be simpler for me, though, to have the list of all rooms as an associative array where the keys of each element is the same as the ID it contains. To do that, I utilized a code similar to this in a for loop:
roomsList[rooms[v].ID] = rooms[v];
So that the result would be:
[a001: {...}, a002: {...}, ...]
I then proceeded to pass this style of array, and not the standard one with a numeric index, as a prop to the next component as such:
<StatsBreakdown stats={computedStats.current} roomsList={roomsList} />
BUT
Now, the next component sees that prop as an empty array.
Even more weirdly, if I initialize that roomsList array with a random value [0] and then do the same process, I end up with:
I cannot cycle through the array with .map, and, according to JS, the length is actually 0, it's not only Google Chrome.
Is there something I'm missing about the way JSX, JS or React work?
Your original roomsList was an array of objects, whose indices were 0,1,2 etc. roomsList[rooms[v].ID] = rooms[v]; implies you are inserting elements not using a number but an alphanumeric string. Hence your resulting array is no longer an array but an object.
So we can cycle over the object using Object.keys().
const renderRoomDets = Object.keys(roomsList).map(room => {
roomOwner = roomsList[room].owner_id;
return (
<div>
<p>{`Room Owner ${roomOwner}`}</p>
</div>
);
});
But I believe your original form is ideal, because you are reaping no special benefits from this notation.
A better alternative maybe using .find() or .findIndex() if you want iterate over an array based on a specific property.
const matchedRoom = roomsList.find(room => room.ID === 'Srf4323')
Iterate the new array using its keys not indexes.
Or even better store your data in an actual object instead of an array since you're using strings for ids.
First define your object like so:
let data = {};
Then start adding records to it. I'd suggest deleting the ID attribute of the object since you're storing it in the key of your record, it's redundant, and it won't go anywhere unless u delete the entry.
data[ID] = row;
To delete the ID attribute (optional):
row.ID = null;
delete row.ID;
Then iterate through it using
for(let key in data){}
I have an array like below
arr=[];
arr[0]={"zero": "apple"};
arr[1]={"one": "orange"};
arr["fancy"]="what?";
but i am getting length as 2 when i do console.log(arr.length) even though i am able to console all the values .
and not able to get all values while doing console.log(JSON.stringify(arr))
What is the issue here.
here is the link to fiddle fiddle
.length is a special property in Javascript arrays, which is defined as "the biggest numeric index in the array plus one" (or 2^32-1, whatever comes first). It's not "the number of elements", as the name might suggest.
When you iterate an array, either directly with for..of or map, or indirectly with e.g. JSON.stringify, JS just loops over all numbers from 0 to length - 1, and, if there's a property under this number, outputs/returns it. It doesn't look into other properties.
The length property don't work as one will expect on arrays that are hashtables or associative arrays. This property only works as one will expect on numeric indexed arrays (and normalized, i.e, without holes). But there exists a way for get the length of an associative array, first you have to get the list of keys from the associative array using Object.keys(arr) and then you can use the length property over this list (that is a normalized indexed array). Like on the next example:
arr=[];
arr[0]={"zero": "apple"};
arr[1]={"one": "orange"};
arr["fancy"]="what?";
console.log(Object.keys(arr).length);
And about this next question:
not able to get all values while doing console.log(JSON.stringify(arr))
Your arr element don't have the correct format to be a JSON. If you want it to be a JSON check the syntax on the next example:
jsonObj = {};
jsonObj[0] = {"zero": "apple"};
jsonObj[1] = {"one": "orange"};
jsonObj["fancy"] = "what?";
console.log(Object.keys(jsonObj).length);
console.log(JSON.stringify(jsonObj));
From MDN description on arrays, here, "Arrays cannot use strings as element indexes (as in an associative array) but must use integers."
In other words, this is not Javascript array syntax
arr["fancy"]="what?";
Which leads to the error in .length.
I've spent the last couple hours going through some very similar answers to the above question but after a few implementations of loops and reduce I still have not gotten the solution I need.
I am getting an array of objects via service calls. I am pushing those controller array objects to another array because I need a single array to load data into a multi select. I.E.
StatesService.getAreaCities().then(function(response) {
controller.cities = response.data.rows;
controller.areaOptions.push(controller.cities);
});
StatesService.getAreaStates().then(function(response) {
controller.states = response.data.rows;
controller.areaOptions.push(controller.states);
});
controller.areaOptions = [];
This is an example of how I expect and need my array object to look.
With no modification this is how my array looks with those array objects pushed in.
How do I get the above data structure like the 1st image, an array of objects? I tried a solution with reduce()
var newCities = controller.cities.reduce(function(city){
return controller.city;
}, {});
controller.areaOptions.push(newCities);
but it wasnt what I was looking for because it returned a single object with all city property and all its values. I need each object to contain city and its value.
EDIT
I figured out the solution! Thanks to Lex.
I looped over each object in the array in each service and pushed the property.
Thanks to all for steering me in the right direction to figure this out, even the person that downvoted me :)
StatesService.getAreaCities().then(function(response) {
controller.cities = response.data.rows;
controller.cities.forEach(function(city){
controller.areaOptions.push(city);
});
});
Looks like response.data.rows is an array. So when you push response.data.rows into controller.areaOptions you are adding the rows array as an array element. (Basically making it a 2-dimensional array)
You should use Array.prototype.concat
I have an object that I am pushing some ints, strings and arrays into an array. And I want to get the length of the array that is within said array.
This is my code
var all_categories = [];
all_categories.push({
title: theTitle,
id: theId,
sub: subcategories
});
Now I know that all_categories.length is the general way of getting the length and I believe that I can't run all_categories[0].sub[0].length will not work because the function does not exist.
Suggestions for a solution or work around?
In your statement all_categories[0].sub[0].length refers to the length of the first element of array named sub.
In order to see length of the array you should call:
all_categories[0].sub.length
Assuming that subcategories is the array you want the length of, take out the second [0]. You aren't trying to get the length of the first subcategory, you're trying to get the number of subcategories.