Check if multiple arrays of the same variable name contain any items - javascript

The example code below uses a mix of razor and Javascript. The RenderChart function takes in dates. The dates var returns an array of dates. I'm wondering how I can check all the date arrays combined to see if any of them contain any items or in this case date strings.
foreach (MeasurementTypeGroup group in Model.MeasurementTypeGroups){
var dates = #(Html.Raw(dates)); // dates returns []
RenderChart( dates);
console.log(dates); //console would display something like " [] [] [] or [] [3/2/12] []
}
Initially I was using an if condition to check the length
if(dates.length === undefined || dates.length === 0) {
//do something
}
this partially works, but it does this on every iteration in the foreach loop rather than on a total of all the date arrays. I'm guessing I need to return another variable and then push the contents of one into the other but I'm having an issue figure out how to do this. Thanks for any help!

you can use concat to combine all the arrays into a single one.
http://www.w3schools.com/jsref/jsref_concat_array.asp
var allDates = []
foreach (MeasurementTypeGroup group in Model.MeasurementTypeGroups){
var dates = #(Html.Raw(dates)); // dates returns []
allDates.concat(dates);
}
RenderChart(allDates);

Related

Checking if the array has duplicates apart from one element Javascript Dice

Hi im struggling to impliment a function to simply check if an array has all the same numbers apart from one.
I have tried a few methods now and i feel like im getting nowhere.
The reason for this is for a dice game the user can select a number of dices and then roll and score bonus points for duplicate numbers and other sequences ect..
I thought it would be simple to check if the array had all duplciates apart from one element in the array but i cant get it to work.
I was thinking of something like check the elements in the aray and see if the all the elements are the same value apart from one by using something with the array.length-1.
Examples dice values which would be true:
[1,2,2,2] or [4,4,2,4] (for 4 dice) //true
[1,1,6] (for 3 dice )//true
I tried something like this :
function countDuplicate(array){
var count=0;
var sorted_array=array.sort();
for (let i=1;i<sorted_array.length;i++)
{
if (sorted_array[i] ==sorted_array[i+1]){
count+=count;}
}
if (count===sorted_array.length-1){
return true;
}
return false;
}
but it doesnt seem to work.
Hope this is enough sorry im new to javascript and stackoverflow.
One way to implement this is to build an array of counts of each of the values in the array. This list can then be checked to ensure its length is 2 and the minimum count is 1:
const countDuplicate = (array) => {
let counts = Object.values(array.reduce((c, v) =>
(c[v] = (c[v] || 0) + 1, c), {}));
return counts.length == 2 && Math.min(...counts) == 1
}
console.log(countDuplicate([1,2,2,2]));
console.log(countDuplicate([4,4,2,4]));
console.log(countDuplicate([1,1,6]));
console.log(countDuplicate([2,2,4,4]));
console.log(countDuplicate([1,2]));
This is using Set and it compares the length of original array and array of removed duplicates:
const hasDuplicates = (arr = []) => {
const noDuplicates = [...new Set(arr)];
return arr.length !== noDuplicates.length;
};
console.log(hasDuplicates([1,2,3]));
console.log(hasDuplicates([1,2,3,1]));
if you're simply just wanting to check if all values are the same except for one in array you can just use this.
function oneMultiple(array) {
const set = new Set(array)
return set.size === 2
}
if you want to simply use one values USE THIS
function oneMultiple(array) {
const set = new Set(array)
return set.size === 2
}

Getting object from array of objects matching values inside and array of dates with lodash

i have an array of obejcts that has this structure
let events = [ {
"initDate": "2019-11-20",
"finalDate": "2019-11-22",
"intermediateDates": [
"2019-11-20",
"2019-11-21"
],
"priority": 1
},....]
So, i'm trying to get the object that matches from a given array of dates for example :
let filteredDays = [
"2019-11-20",
"2019-11-21",
"2019-11-22"
]
i'm trying with lodash like this:
let eventsFound= [];
let intersection = _.map( this.events,function(value){
let inter = _.intersection(value.intermediateDates,filteredDates);
console.log(inter);
if(inter != []){
foundEvents.push(value);
return value;
}else{
return false;
}
});
when i console log inter i get the first array with values then the next arrays are empty but it keeps pushing all the events into the foundEvents Array and the returned array is the same as the events array.
You're comparing two arrays using !=. In javascript [] != [] is always true. To check if an array is empty, use length property like arr.length == 0.
Use filter instead of using map like a forEach.
To check existance use some/includes combo instead of looking for intersections.
So, filter events that some of its intermediateDates are included in filteredDates:
let eventsFound = _.filter(this.events, event =>
_.some(event.intermediateDates, date =>
_.includes(filteredDates, date)
)
);
The same using native functions:
let eventsFound = this.events.filter(event =>
event.intermediateDates.some(date =>
filteredDates.includes(date)
)
);

JavaScript loop, create object, but shows zero in length

I have a javascript method, where I'm trying to group my data by 'date', which works fine.
But when I look at the length of my object it shows, 'zero'.
Is there a better way to do this? and keep the length of the new variable?
groupByDate(snapshot) {
let list = []
this.orders.reduce(function (a, c) {
if(!list[c.date]) {
list[c.date] = [];
}
list[c.date].push(c);
});
this.ordersByDate = list
console.log(list)
}
You are pushing properties into an array. You are not setting the indexes of the array. So you should be using an object and not an array. Your use of reduce is also not correct. You are treating it like a forEach loop.
So use an object and use reduce the way it is supposed to be
let list = this.orders.reduce(function (o, c) {
o[c.date] = o[c.date] || []
o[c.date].push(c)
return o
}, {})
console.log(Object.keys(list).length)
I would use a dictionary (key, values) for that:
list {
date1: [obj1-1, obj1-2, ...],
date2: [obj2-1, obj2-2, ...],
...
}
list = {};
this.orders.forEach(order => {
if (!list.hasOwnProperty(order.date)) {
// If it is the first time we meet this date, create an array with th first element
list[order.date] = [order];
} else {
// We have already meet the date, thus the key exists and so do the array. Add element to array
list[order.date].push(order);
}
});
It seems you have an array and its indexes are the dates. I assume the dates are big numbers (date from 1970 in milliseconds, something like that), which may lead to having a very very big array 99,9% empty. That is why according to me you should use an object and not an array.
Or maybe those are not dates but id's of dates ?

Chaining methods on array display as undefined [duplicate]

This question already has answers here:
How can I create a two dimensional array in JavaScript?
(56 answers)
Closed 5 years ago.
const array = new Array(9).fill([]).forEach(function(value, index, arr) {
arr[index] = Array(9).fill(0);
console.log(index, arr[index]); // This line report properly by creating
}); // new array.
console.log(array); // Reported as underdefined.
However, if redefine as below, it works as expected.
const array = new Array(9).fill([]);
array.forEach( function(value,index,arr){
arr[index] = Array(9).fill(0);
console.log(index,arr[index]);
});
console.log(array);
I would like to define multiple dimensional arrays within one line used as this state command.
But what is the problem for scenario 1 where bounded forEach methods array definitions work fine?
But what is the problem for scenario 1 where bounded forEach methods
array defnitions works fine.
Problem is forEach returns undefined
I woule like to define multiple dimensional arrays within one line
used as this.state command.
You can use map for the same
var output = new Array(9).fill([]).map( function(value,index,arr){
return Array(9).fill(0); //return the inner array
});
Or as #bergi suggested, you can use Array.from as well
var output = Array.from(Array(9)).map( function(value,index,arr){
return Array(9).fill(0);
});
As other answers have already mentioned Array.forEach returns undefined or does not return anything, you cannot use it.
As an alternate approach, you can use Array.from.
Following is a sample:
var output = Array.from({
length: 9
}, () => {
return Array.from({
length: 9
}, () => 0)
});
console.log(output)
Also, one more issue with your code is, you are using an object in Array.fill. What array.fill does is, it will create the value to be filled first and then fill it in all items.
var output = new Array(9).fill([]);
output[0].push(1);
console.log(output)
In you check the output, it says /**ref:2**/, but if you check in console, you will notice that all items will have item 1. So you should avoid using objects with Array.fill.
You want to generate array of 9 arrays filled with 0 and return it to variable.
You can achieve this using map method.
const array =
new Array(9)
.fill([])
.map(function(){
return Array(9).fill(0);
});
console.log(array);
p.s. no value, index and etc needed to pass to map methods argument in Your case
Array.prototype.forEach returns undefined. Just call the forEach like below.
const array = new Array(9).fill([])
array.forEach( function(value,index,arr){
arr[index] = Array(9).fill(0);
});
// [
// [0, 0, 0, ...],
// ...
// ]
Using map would be another choice, but I don't vote for it because it creates yet another array in memory.

Looping through an array with conditions

I'm having a tough time figuring out how to loop through an array and if certain items do exist within the array, i'd like to perform a .slice(0, 16) to kind of filter an already existing array (lets call that existing array "routes").
For example, a previous process will yield the following array:
points = ['=00ECY20WA200_RECV_P1SEL',
'=00ECY20WA200_RECV_P2SEL',
'=00RECV_C1A_EINCSCMPP1',
'=00RECV_C1A_EINCSCMPP2',
'=00BYPS_C1A_EINCSCMP',
'=00ECY20WA200_BYPS_SPSL1',
'=00ECC92AG184YB01',
'=00ECC92AG185YB01',
'=00ECC92AG186YB01',
'=00ECC92AG187YB01',
]
So if any of the above items exist in the "points" Array, which in this case they all do (but in some cases it could just be 1 of the 10 items existing there), I'm trying to perform routes.slice(0, 16) to the other already existing array.
I've tried lots of different ways (for loops with if statements) and at this point I'm not sure if its my syntax or what, but I'm back at square 0 and I don't even have a competent piece of code to show for. Any direction would be greatly appreciated.
You could use a hash table for checking and filtering.
var points = ['=00ECY20WA200_RECV_P1SEL', '=00ECY20WA200_RECV_P2SEL', '=00RECV_C1A_EINCSCMPP1', '=00RECV_C1A_EINCSCMPP2', '=00BYPS_C1A_EINCSCMP', '=00ECY20WA200_BYPS_SPSL1', '=00ECC92AG184YB01', '=00ECC92AG185YB01', '=00ECC92AG186YB01', '=00ECC92AG187YB01'],
hash = Object.create(null),
filtered = points.filter(function (a) {
if (!hash[a.slice(0, 16)]) {
hash[a.slice(0, 16)] = true;
return true;
}
});
console.log(filtered);
ES6 with Set
var points = ['=00ECY20WA200_RECV_P1SEL', '=00ECY20WA200_RECV_P2SEL', '=00RECV_C1A_EINCSCMPP1', '=00RECV_C1A_EINCSCMPP2', '=00BYPS_C1A_EINCSCMP', '=00ECY20WA200_BYPS_SPSL1', '=00ECC92AG184YB01', '=00ECC92AG185YB01', '=00ECC92AG186YB01', '=00ECC92AG187YB01'],
pSet = new Set,
filtered = points.filter(a => !pSet.has(a.slice(0, 16)) && pSet.add(a.slice(0, 16)));
console.log(filtered);
EDIT: So it seems like you want to remove an element from an array called routes for each element in the points array. This is how you could do this:
function removeBrokenRoutes(brokenPoints, routes){
for(let pt of brokenPoints){
let index = routes.indexOf(pt);
if(index !== -1) routes.splice(index,1);
}
return routes;
}
Keep in mind that the larger the arrays, the more time this is going to take to complete.
You could use the filter and indexOf methods in combination:
var arr = [/* all the data you're checking against */];
var points = [/* the data you're checking for */];
var filteredArr = arr.filter(function(x) {
// will return -1 if the point is not found
return points.indexOf(x) !== -1;
});
filteredArr will contain all the points that appear in both arrays. The filter function works by taking a function with one argument x, which represents each item in the array. if the function returns true, the item will be added to the new array (filteredArr), and if false the function will move on to the next item. indexOf will check if the item is found in the other array. Also it is important to note that you will need a more complex solution (such as a hashtable) if the data set is very, very large as this is not necessarily the most performant method. But it's a good place to start as it is easy to understand.

Categories

Resources