get next location of element in array instead of first with indexOf - javascript

I'm using arr.indexOf('NN') to obtain the first location of 'NN' in array arr. How can I obtain the second / next location of 'NN' in the array after the first. Or even after location i, if I am traversing the array in a for loop?

This will log an array with all the indices where the contained values match 'NN' :
var arr = [0,1,2,3,'NN',5,6,'NN',8,9];
var locations = [];
for(var i = 0; i < arr.length; i++){
if(arr[i] === 'NN'){
locations.push(i);
}
}
console.log(locations); // => [4,7]

Related

New array counter within nested loops

I am studying JavaScript and I believe I understand how these loops work. However, I got an exercise where I didn't understand which was the function of the counter for a new array being filled. This is the exercise:
var animals = ["goat", "cat", "crow"];
var products = ["milk", "cheese", "burger"];
var foodItems = [];
var k = 0;
for (var i = 0; i < animals.length; i++) {
for (var j = 0; j < products.length; j++) {
foodItems[k] = animals[i] + products[j];
k++;
}
}
console.log(foodItems);
The code above produces the array ["goatmilk", "goatcheese", "goatburger", "catmilk", "catcheese", "catburger", "crowmilk", "crowcheese", "crowburger"]. If I take out the [k] counter, it gives me an 1 element array [crowburger]; if I put a zero as the foodItems counter, it gives me [crowburger] as well, but bigger numbers produce undefined elements in the array before crowburger (i.e. foodItems[10] equals [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, "crowburger"]).
My question: what does the [k] counter do and why if it is replaced by numbers it produces undefined elements plus [crowburger?]
k is the index of the array. An array is a sorted list of elements and the standard access is to use an index to get the element at the given index. index is zero based, it starts from zero for the first element of the array.
If you take always the same index, the element at the given index is replaced by the new element.
The pattern
array[index] = value:
index++;
is like Array#push, which add the element at the end of the array without maintaining an index by hand.
array.push(value);
The k is the outer iterator. It's controlling the index of the global foodItems empty array, because if you declared it inside the scope of the loop, it wouldn't be accessible outside of the loop, and would vanish. So, commonly, you declare the outer array and iterator, and as you iterate through the loop, you're adding the values to the array and iterating over it.
Think of it like this:
var k = 0 // So we start on the first index of the foodItems array
var foodItems = []; // So it is declared empty at start
Here's what it's basically doing:
foodItems[k] (which is currently zero) is equal to animals[0] + products[0]... Then foodItems[1] is animals[0] + products[1] and so on.
The reason you can't use any number is because it doesn't have any indices when it starts, and you can't access the 5th (for example) element of an empty array.
The k counter is the index of the foodItems - In your case it cannot go higher than 9 which is 3x3.
So first time around you have k=0
foodItems[0] = "goat"+"milk"
second k++ (increment k by one)
foodItems[1] = "goat"+"cheese"
If you do not want the counter, just push to foodItems
i.e change foodItems[k] = animals[i] + products[j]; to foodItems.push(animals[i] + products[j]);
It will add the string to a new empty spot in foodItems on each push, making foodItems longer for each push
var animals = ["goat", "cat", "crow"];
var products = ["milk", "cheese", "burger"];
var foodItems = [];
for (var i = 0; i < animals.length; i++) {
for (var j = 0; j < products.length; j++) {
foodItems.push(animals[i] + products[j]);
}
}
console.log(foodItems);

Output duplicate elements natively in array with JavaScript

For example, I have such array: var number2 = [1,3,4,1,5,6,3] and I want to output only repeated elements such as 1 and 3 without any method. My code is as follows:
for(let i=0; i<number2.length; i++){
for(let j=0; j<number2.length; j++){
if([i]!==[j] && number2[i]===number2[j]){
console.log(number2[i]);
}
}
}
But it doesn't work how I want.
[i] !== [j] Should be just i !== j.
number2[i] === number2[j] is correct.
If you need less complexity [instead of O(n^2), O(n)] you can use a map over there. just loop over the array you have, and put each digit in map with its occurrences.
var map = new Map();
for(var i=0; i<arr.length; i++){
var val = map.get(arr[i]);
// if key found [such as, if the value already exist in array]
if(!isNaN(val))
map.set(arr[i], val+1);
// if key not found[such as, if the value found for the first time in array]
else
map.set(arr[i], 1);
}
// iterate over the map, and print only those value whose occourance is >1.
for(var [key, value] of map){
if(value > 1)
console.log(key);
}

Updating array based on newer objects in another array

I have a question that is hard to describe. It's a tale of two arrays.
I have one array holding 50 objects. Per object, I want to call its specific property "IDnumber".
The second array is one that has 5 variables containing all of the mentioned 50 objects's "IDnumber" property, with each variable having a set of 10 IDnumbers: var1 is the IDnumbers of the first 10 objects, var2 is is the IDnumbers of the second set, and so on until the 50th object's ID number.
This is where it gets hard.
If I want to add in a new object in the first array, so that there'll be 51 objects, then I want to update the second array with a 6th variable, that contains all the remaining objects' IDnumbers (in this case just the 1). I want array2's length to be dependent on array1's length.
var arr1 = [], obj = {"IDNumber": "1"};
//this is an example array, all objects have the same ID here, but not in my real array
for (var i = 0; i < 51; i++) {
arr1.push(obj);
}
var var1 = [arr1[0]["IDNumber"], arr1[1]["IDNumber"], arr1[2]["IDNumber"], arr1[3]["IDNumber"], arr1[4]["IDNumber"], arr1[5]["IDNumber"], arr1[6]["IDNumber"], arr1[7]["IDNumber"], arr1[8]["IDNumber"], arr1[9]["IDNumber"]];
//the other remaining possible variables.
var arr2 = [var1, ...]; //No clue as how to take that on
How do I do that? How do I create an array that updates itself with newer possible variables like that? Each variable must have a max of 10 objects' IDnumbers.
Suppose array1 contains your array of objects. The other one is array2 containing an array of arrays, each sub array has length 10 like you stated
You can split array1 into groups of 10 and put in array2 like this
function slice10(arraysOfObject) {
var array2 = [];
var leftOver = arraysOfObject.length % 10;
var groupsOfTen = (arraysOfObject.length - leftOver)/10;
for (var i = 0; i < groupsOfTen; i++) {
array2.push([]);
for (var j = i*10; j < i*10 + 10; j++)
array2[i].push(arraysOfObject[j]["IDNumber"]);
}
//now take care of the leftover
if (leftOver > 0) {
array2.push([]);
for (var i = groupsOfTen*10; i < arraysOfObject.length; i++)
array2[array2.length-1].push(arraysOfObject[i]["IDNumber"]);
}
return array2;
}
You could create a function to deal with adding an object to the two different data structures, and use that function also for adding the first 50 objects:
function addObject(arr1, arr2, obj) {
if (arr1.length % 10 == 0) arr2.push([]);
arr1.push(obj);
arr2[arr2.length-1].push(obj.IDNumber);
}
var arr1 = [], arr2 = [];
for (var i = 0; i < 51; i++) {
addObject(arr1, arr2, {"IDNumber": i + 1000}); // some dummy ID value
}
console.log(arr2);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Generate random display of array elements in an array of arrays?

Ok, i have an array that contains at least two or more arrays that can contain several objects:
array[ [array[n], array[n], array[n], etc...]
my question is how to loop through and randomly pick one object from lets say array[0][1] and randomly pick another object from array[0][15] and produce no duplicates while appending each one to the page.
I have an example of what i am working on here http://jsfiddle.net/I_am_Chris/Yn5Wy/
var randObj1;
var randObj2;
var randArray;
for(i=o; i<array.length; i++){
randArray = array[i]; //get length of "nested" arrays within the array
for(n=0;n<randArray.length; n++){
randObj1 = [][].name
randObj2 = [][].name
}
}
I have tried shuffling the arrays, but that just shuffles the individual arrays, but not the outcome i need.
OK, it sounds like you want N pairs of two choices where each item in the pair is from a different array and you want no repeats.
The no repeats part is going to be efficient and run less risk of infinite looping if you create a parallel data structure that we can remove items from once chosen. This is flatly the simplest way to avoid duplicatesw without having to do a search each time. It also allow you to easily know how many choices are left in any given array in case there are no more possibilities. Here's how you could do that:
function getPairs(origData, N) {
// make copy of the data we can modify to keep track of which choices are used
var copyData = [];
for (var i = 0; i < origData.length; i++) {
copyData.push(origData[i].slice(0));
}
function getRandomValueAndRemove(skipArray) {
var randArray;
// select an array that isn't skipArray
do {
randArray = Math.floor(Math.random() * copyData.length);
} while (randArray === skipArray) ;
// select an item in that array
var randIndex = Math.floor(Math.random() * copyData[randArray].length);
var value = copyData[randArray][randIndex];
// remove that item from copyData
copyData[randArray].splice(randIndex, 1);
// if one of the arrays we selected is now empty, then remove it
if (!copyData[randArray].length) {
copyData.splice(randArray, 1);
// this array is gone so we don't have to worry about selecting it again
randArray = -1;
}
// return data and which array it is
return {value: value, whichArray: randArray};
}
// get N pairs
var pairs = [];
for (i = 0; i < N && copyData.length > 1; i++) {
var item1 = getRandomValueAndRemove();
var item2 = getRandomValueAndRemove(item1.whichArray);
pairs.push([item1.value, item2.value]);
}
// pairs contains an array of pairs
// where each item in a pair is from a different source array
// like this
// [[a, b], [c,d], [e,f]]
return pairs;
}
Working demo: http://jsfiddle.net/jfriend00/sy6XF/
If the pairs can contain any two objects, then it's simpler to do it like this.
You have some data that looks like this (array of arrays):
var origData = [[...], [...], [...]];
You can create a temporary single flat array with all the objects in it. Generate one random number to get an object. Then, remove that object from the temporary array and repeat the process (with a now shorter array). This is the simplest way of avoiding duplicates because you remove the ones you've used from the temporary array and select random choices from the remaining elements.
Here's a code example for the second option:
var origData = [[...], [...], [...]];
var flatData = [];
var item;
// put everything into flatData
for (var i = 0; i < origData.length; i++) {
flatData.push.apply(flatData, origData[i]);
}
var pairs = [];
// now select N random pairs
for (var i = 0; i < N && flatData.length > 1; i++) {
var rand = Math.floor(Math.random() * flatData.length));
var obj1 = flatData[rand];
// now remove that element from flatData so we won't pick it again
flatData.splice(rand, 1);
// get second randome value
rand = Math.floor(Math.random() * flatData.length));
var obj2 = flatData[rand];
pairs.push([obj1, obj2]);
}
// pairs contains an array of pairs
[[a, b], [c,d], [e,f]]
to generate a random number, use Math.random()
Math.random() generates a random number between 0 and 1. Then multiply by the length of the nested array to generate an index for the element you want from the nested array. Repeat the random number generation for the second index as long as it's equal to the first index. Store the results in the results array.
var results = [];
var genRandNum = function(max) {
return Math.random() * (max - 1);
}
for(var i = 0; i < array.length; i++) {
var nestedArray = array[i];
var randIndex1 = genRandNum(nestedArray.length);
results.push(nestedArray[randIndex1]);
do {
var randIndex2 = genRandNum(nestedArray.length);
} while (randIndex1 === randIndex2);
results.push(nestedArray[randIndex2]);
return results;
}
FYI, didn't test this because it wasn't clear what your test should produce.

Empty array after pushing to another array

I want to push array A to B inside cycle and then and for every iteration of B i need to delete array A and create new one. I get all data before clearing the array, but after clearing I get array B with empty values
Code :
for (i = 0; i < XArray.length; i++) {
var pointsArray = [];
for (j = 0; j < XArray.length; j++) {
if (XArray[i] == XArray[j]) {
pointsArray.push([parseFloat(YArray[i]), parseFloat(ZArray[i])]);
}
}
dataSource.push({
name: i,
data: pointsArray
});
pointsArray.length = 0;
}
The last line
pointsArray.length = 0;
removes every element in the array you created in the first line. And since all objects are assigned by reference (and arrays are objects), the data property of the object will now point to an empty array. Here is a simplified example:
var a = [1, 2];
var b = a;
a.length = 0;
console.log(b); // [] -- an empty array
So, your current code has the same effect as
dataSource.push({
name: i,
data: []
});
Solution: Just remove the last line and it will work as expected.

Categories