I want to check if all the integers present in a number has the same frequency.
Sample Input :
1212
Sample Output :
True
I am able to get the frequency using reduce function . But not able to compare the values.
let countOccurrences = arr => arr.reduce((accm,x)=> (accm[x] = ++accm[x] || 1,accm),{});
var obj = (countOccurrences([2,3,4,2,3,4]))
for(var i in obj)
console.log(obj[i+1]);
if(obj[i]===obj[i+1]){
console.log("true");
}else{
console.log("false");
}
//end-here
});
One way would be to use the Array every() method to check that every value in your object is equal to the first one (after converting to an array of values).
const countOccurrences = arr => arr.reduce((accm,x)=> (accm[x] = ++accm[x] || 1,accm),{});
const obj = countOccurrences([2,3,4,2,3,4]);
const same = Object.values(obj).every((el, _, arr) => el === arr[0]);
console.log(same);
You can use Set to remove dupicates
let countOccurrences = arr => arr.reduce((accm,x)=> (accm[x] = ++accm[x] || 1,accm),{});
var obj = (countOccurrences([2,3,4,2,3,4]));
const isSameFrequency = (new Set(Object.values(obj))).size == 1;
console.log(isSameFrequency);
Related
I am trying to sort some numbers, and I want to count the number of times that an array has a certain number.
My question is more about the structure of an the array than the counting the number part. I would like to build an array that looks like this below.
let numbers = [1,2,3,4,4,4,5,5,6];
How could I make the data structure below?
numbers[3].count // this will be equal to 3 after I loop through;
How do I make each part of the array have an object parameter?
Do I just loop through like so?
for (let i = 0; i < numbers.length; i++){
numbers[i] = {
count: 0
}
}
I understand this wont give me the right count, but I don't care about that part of the problem. I would like to solve that on my own. I just need to be sure that this is the correct way to add the object parameters.
I would build these functions on my own. Something like this
You can copy and paste this in the console of your browser.
// my numbers list
const numbers = [1, 2, 3, 4, 4, 4, 5, 5, 6];
// reduced to unique entries
const uniques = [...new Set(numbers)];
// function to count occurrences in my list of number
const count = (n) => numbers.filter((num) => num === n).length;
// you can test here
console.log(`counting ${uniques[4]}s`, count(uniques[4]));
// get these as object
console.log(uniques.map((unique) => ({[unique]: count(unique)})))
Simplest way to achieve this by using Array.forEach().
let numbers = [1,2,3,4,4,4,5,5,6];
const obj = {};
numbers.forEach((item) => {
obj[item] = (obj[item] || 0) + 1;
});
console.log(obj);
const numbers = [1,2,3,4,4,4,5,5,6];
const counts = {};
numbers.forEach((x) => counts[x] = (counts[x] || 0) + 1);
console.log(counts)
You can use the Array#reduce() method to group elements together into sub arrays. Since arrays have a length property that gives the the number of elements this can be applied to each group of like elements. We do not need to create a new count property.
let numbers = [1,2,3,4,4,4,5,5,6];
const freq = numbers.reduce(
(acc,cur) => ({...acc,[cur]:(acc[cur] || []).concat(cur)})
);
console.log( freq[4] );
console.log( freq[4].length );
Alternatively, you can put the numbers in an object and get all the unique elements, then for each unique element define a get property that groups like elements together using the Array#filter() method. Again, the length array property can be used to return the number of elements for each unique element.
const o = {numbers: [1,2,3,4,4,4,5,5,6]};
o.uniq = [...new Set(o.numbers)];
o.uniq.forEach(n => Object.defineProperty(
o,n,{get:() => o.numbers.filter(num => num === n)}
));
console.log( o[5] );
console.log( o[5].length );
Reduce is perfect for these kinds of problems.
const numbers = [1,2,3,4,4,4,5,5,6];
const countedObject = numbers.reduce((tmpObj, number) => {
if (!tmpObj[number]) {
tmpObj[number] = 1;
} else {
tmpObj[number] += 1;
}
return tmpObj
}, {});
console.log(countedObject);
if you feel the need to nest it further you can of course do this.
But if count is the only property you need, I'd suggest sticking to the first version.
const numbers = [1,2,3,4,4,4,5,5,6];
const countedObject = numbers.reduce((tmpObj, number) => {
if (!tmpObj[number]) {
tmpObj[number] = {count: 1};
} else {
tmpObj[number].count += 1;
}
return tmpObj
}, {});
console.log(countedObject);
I am trying to work on a problem where I want to remove all the occurrences of similar value in an array
eg.
var sampleArr = ["mary","jane","spiderman","jane","peter"];
and I am trying to get result as => ["marry","spiderman","peter"]
how do I get this?
You can use filter()
var arr = ["mary","jane","spiderman","jane","peter"];
var unique = arr.filter((x, i) => arr.indexOf(x) === i);
console.log(unique);
var sampleArr = ["mary","jane","spiderman","jane","peter"];
var unique = [];
var itemCount = {};
sampleArr.forEach((item,index)=>{
if(!itemCount[item]){
itemCount[item] = 1;
}
else{
itemCount[item]++;
}
});
for(var prop in itemCount){
if(itemCount[prop]==1){
unique.push(prop);
}
}
console.log(unique);
Check this.
You can count the frequency of the character and just pick the character whose frequency is 1.
const arr = ["mary","jane","spiderman","jane","peter"];
frequency = arr.reduce((o,ch) => {
o[ch] = (o[ch] || 0) + 1;
return o;
}, {}),
unique = Object.keys(frequency).reduce((r,k) => frequency[k] === 1? [...r, k]: r, []);
console.log(unique);
You can use filter:
var sampleArr = ["mary","jane","spiderman","jane","peter"];
var result = sampleArr.filter((e,_,s)=>s.filter(o=>o==e).length<2);
// or with reduce and flatmap
const result1 = Object.entries(sampleArr.reduce((a,e)=>(a[e]??=0, a[e]++, a),{})).flatMap(([k,v])=>v==1 ? k: []);
console.log(result)
console.log(result1);
lot of solution, here easy solution to understand using match to have the occurence and filter to eliminate:
var arr = ['ab','pq','mn','ab','mn','ab'];
var st = arr.join(",");
result = arr.filter(it => {
let reg = new RegExp(it, 'g');
return st.match(reg).length == 1;
});
console.log(result);// here ["pq"]
filter seems to be your best bet here if you need extremely robust performance. No real need for jQuery in this instance. Personally, I would opt for readability for something like this and instead sort, set duplicates to null, and then remove all null values.
var sampleArr = ["mary","jane","spiderman","jane","peter"];
var result = sampleArr.sort().forEach((value, index, arr) => {
// if the next one is the same value,
// set this one to null
if(value === arr[value + 1])
return arr[index] = null;
// if the previous one is null, and the next one is different,
// this is the last duplicate in a series, so should be set to null
if(arr[value - 1] === arr[index + 1] !== value)
return arr[index] = null;
return
})
.filter(value => value === null) //remove all null values
console.log(result);
I have an array of strings like this:
const strings = [
"author:app:1.0.0",
"author:app:1.0.1",
"author:app2:1.0.0",
"author:app2:1.0.2",
"author:app3:1.0.1"
];
And I want to filter them so that only the ones that have the latest versions for the given "author:name" are left, thus removing ones that are not the latest (i.e. the "1.0.1" ones).
My expected result is this:
const filteredStrings = [
"author:app:1.0.1",
"author:app2:1.0.2",
"author:app3:1.0.1"
];
Any way to do this simply?
You can do it with two loops first one find new ones second one check which is bigger
const strings = [
"author:app:1.0.0",
"author:app:1.0.1",
"author:app2:1.0.0",
"author:app2:1.0.2",
"author:app3:1.0.1"
];
filteredones = [];
strings.forEach(element => {
var arr = element.split(":");
var isnew = true;
var found = filteredones.find(function(element2) {
var x = element2.split(":");
return x[1] == arr[1] && x[0] == arr[0]
});
if (found == undefined) {
filteredones.push(element);
}
});
for (var i = 0; i < filteredones.length; i++) {
element = filteredones[i];
var arr = element.split(":");
var isnew = true;
var found = strings.find(function(element2) {
var x = element2.split(":");
return x[1] == arr[1] && x[0] == arr[0] && x[2] > arr[2]
});
if (found != undefined) {
filteredones[i] = found;
}
};
console.log(filteredones);
you can check the value in the last index of the string in each of the elements of the array and if they qualify as a latest one put it to a new array.
You can use an object to store the key/version pairs, and convert to appropriate output on the end. The version comparison can be any of those found here: How to compare software version number using js? (only number)
result = {};
for (var s of input) {
// parts = ["author", "appname", "version"]
var parts = s.split(":");
var i = parts[0] + ":" + parts[1];
if (!result[i] || compareVersion(parts[2], result[i]))
// If not present or version is greater
result[i] = parts[2]; // Add to result
}
result = Object.keys(result).map(k => k + ":" + result[k])
Working demo: https://codepen.io/bortao/pen/LYVmagK
Build an object with keys as app name.
getValue method is calculate the version value so that to compare.
Update object value, when you see the version is recent (value is big).
const strings = [
"author:app:1.0.0",
"author:app:1.0.1",
"author:app2:1.0.0",
"author:app2:1.0.2",
"author:app3:1.0.1"
];
const filter = data => {
const res = {};
const getValue = item =>
item
.split(":")[2]
.split(".")
.reduceRight((acc, curr, i) => acc + curr * Math.pow(10, i), 0);
data.forEach(item => {
const app = item
.split(":")
.slice(0, 2)
.join(":");
if (!res[app] || (app in res && getValue(item) > getValue(res[app]))) {
res[app] = item;
}
});
return Object.values(res);
};
console.log(filter(strings));
I want to sort an array values in an ascending or descending order without using sort().
I have created a function, however I am not satisfied with it.
I believe the code below could be much shorter and more concise.
Please let me know where to modify or you may entirely change the code too. Thank you in advance.
const func = arg => {
let flip = false;
let copy = [];
for(let val of arg) copy[copy.length] = val;
for(let i=0; i<arg.length; i++) {
const previous = arg[i-1];
const current = arg[i];
if(previous > current) {
flip = true;
copy[i] = previous;
copy[i-1] = current;
}
}
if(flip) return func(copy);
return copy;
};
l(func([5,2,8,1,9,4,7,3,6]));
If your input is composed of whole numbers, as in the example, pne option is to reduce the array into an object, whose keys are the numbers, and whose values are the number of times those values have occured so far. Then, iterate over the object (whose Object.entries will iterate in ascending numeric key order, for whole number keys), and create the array to return:
const func = arr => {
const valuesObj = {};
arr.forEach((num) => {
valuesObj[num] = (valuesObj[num] || 0) + 1;
});
return Object.entries(valuesObj)
.flatMap(
([num, count]) => Array(count).fill(num)
);
};
console.log(
func([5,2,8,1,9,10,10,11,4,7,3,6])
);
This runs in O(N) time.
To account for negative integers as well while keeping O(N) runtime, create another object for negatives:
const func = arr => {
const valuesObj = {};
const negativeValuesObj = {};
arr.forEach((num) => {
if (num >= 0) valuesObj[num] = (valuesObj[num] || 0) + 1;
else negativeValuesObj[-num] = (negativeValuesObj[-num] || 0) + 1;
});
return [
...Object.entries(negativeValuesObj).reverse()
.flatMap(
([num, count]) => Array(count).fill(-num)
),
...Object.entries(valuesObj)
.flatMap(
([num, count]) => Array(count).fill(num)
)
];
};
console.log(
func([5,2,8,1,-5, -1, 9,10,10,11,4,7,3,6, -10])
);
For non-integer items, you'll have to use a different algorithm with higher computational complexity.
I have data in which there are arrays. in the array, there is a value which is claimed_value. I need the sum of all claimed_value of arrays. an example I have array all have the claimed_value. but I need to sum of all the claimed_value which have the status=settled in the array.
this is how I'm calling the API.
getClaims(){
if(this.userFilter.company_id){
let url =
'http://api.igiinsurance.com.pk:8888/insurance_IGItakaful/insurance-
api/get_claims.php?company_id='+this.userFilter.company_id;
}else{
let url =
'http://api.igiinsurance.com.pk:8888/insurance_IGItakaful/insurance-
api/get_claims.php?offset=0&limit=200';
}
this.clientData = this.httpClient.get(url).
subscribe(data => {
console.log(data);
this.data = data.records;
var status = 'settled';
var status2 = 'submitted';
var countsettled = this.data.filter((obj) => obj.status ===
status).length;
var countunsettled = this.data.filter((obj) => obj.status ===
status2).length;
console.log(countsettled);
this.countsettled = countsettled;
console.log(countunsettled);
this.countunsettled = countunsettled;
});
}
Your question is more general javascriptthan angular
You can sum element of array by using the Array.reduce function
You can sum on a specific status by filtering first
Ie
const sum = this.data.filter(item => item.status === 'settled')
.reduce((acc, item) => acc + Number(item.claimed_value), 0);
Note that as said in comment you received a string and not a numberso you must convert it at first (see the Number() function in thereduceclosure)) otherwise the+` operator will just concatenate the string
let finalSum = 0;
this.data.forEach((item) => {
if(item.status === 'settled'){
finalSum += item.claimed_value
}
});
console.log("final sum is ", finalSum);
Hello, This will loop on all the arrays in your data list , and add the number of claimed_value to the finalSum .
Hope this will work for you.