Javascript - combine the elements of an multidimensional array [duplicate] - javascript

This question already has answers here:
Finding All Combinations (Cartesian product) of JavaScript array values
(16 answers)
Closed 6 years ago.
I'm trying to combine all elements of a multidimensional Array to have a combination of elements.
e.g. If I have
var array = [
['a'],
['1', '2', '3', '4'],
['A']
];
The result must look like:
["a1A", "a2A", "a3A", "a4A"]
I could realise this result with the following code:
var finalArray = [];
var f1 = 0;
for (var i = 0; i < array.length - 1; i ++) {
f1 = 0;
for (var j = 0; j < array[i].length; j ++) {
for (var k = 0; k < array[i + 1].length; k ++) {
if (finalArray[f1])
finalArray[f1] += array[i + 1][k];
else
finalArray[f1] = array[i][j] + array[i + 1][k];
f1 ++;
}
}
}
console.log(finalArray);
The Problem is if I add more elements to the first or last member, it does not work as expected.
for example this array
var array = [
['a', 'b'],
['1', '2', '3', '4'],
['A']
];
returns:
["a1A", "a2A", "a3A", "a4A", "b1", "b2", "b3", "b4"]
which should be:
["a1A", "a2A", "a3A", "a4A", "b1A", "b2A", "b3A", "b4A"]
Any help to fix my code is highly appreciated.

You could use an iterative and recursive approach for variable length of parts an their length.
function combine(array) {
function c(part, index) {
array[index].forEach(function (a) {
var p = part.concat(a);
if (p.length === array.length) {
r.push(p.join(''));
return;
}
c(p, index + 1);
});
}
var r = [];
c([], 0);
return r;
}
var result = combine([['a', 'b', 'c'], ['1', '2', '3', '4'], ['A', 'B']]);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Related

Merging two strings that are the same, that appear in a row within an array using JS

For example:
const items = ['a', 'a', 'b', 'a', 'a'];
Would become:
['a', 'b', 'a']
Is there a clean way of doing the above using JS?
I have tried:
const items = ['a', 'a', 'b', 'a', 'a'];
const uniqueInRow = [];
for (var i=0; i < items.length; i++) {
item = items[i];
if (item !== item[i++]) {
uniqueInRow.push(item);
}
}
console.log(uniqueInRow);
Try like following:
const items = ['a', 'a', 'b', 'a', 'a'];
const res = []
for(let i = 0; i < items.length; i++) {
if (i === 0 || items[i] !== items[i-1]) res.push(items[i])
}
console.log(res)
You may avoid equal neighbours via oneliner:
vals.forEach((v, i) => (i < vals.length && v === vals[i + 1]) && vals.splice(i, 1))

Turn flat array into 2D array taking equally sized chunks

I'm working on a freecodecamp exercise, and need helping figuring out why my code is not working as intended. So the purpose of this exercise is to:
Write a function that splits an array (first argument) into groups the
length of size (second argument) and returns them as a
multidimensional array.
Why doesn't this code return [[0, 1], [2, 3], [4, 5]]?
function chunk(arr, size) {
// Break it up.
var output = [];
for (var x = 0; x < arr.length; x++) {
if (arr.length >= size) {
output.push(arr.splice([0], size));
} else {
output.push(arr.splice([0], arr.length));
}
}
return output;
}
document.write(JSON.stringify(
chunk([0, 1, 2, 3, 4, 5], 2)
));
Replace the for loop with a much simpler while loop:
function chunk(arr, size) {
// Break it up.
var output = [];
while (arr.length) {
if (arr.length >= size) {
output.push(arr.splice(0, size));
} else {
output.push(arr.splice(0, arr.length));
}
}
return output;
}
document.write(JSON.stringify(
chunk([0, 1, 2, 3, 4, 5], 2)
));
arr.splice also modifies arr. This way, in your example, after the first call of arr.splice(0, size) (note its not [0]), arr only has 4 elements, and after the second call, there are only 2 elements left. Therefore x < arr.legnth gets earlier true than you want it to be.
Another issue is that you only increase x by 1 in each iteration, where it should be size.
overall, this should work
function chunk(arr, size) {
// Break it up.
var output = [];
var l = arr.length;
for (var x = 0; x < l; x+=size) {
if (arr.length >= size) {
output.push(arr.splice(0, size));
} else {
output.push(arr.splice(0, arr.length));
}
}
return output;
}
console.log(chunk([0, 1, 2, 3, 4, 5], 2));
There is another way with modulo.
function chunk(arr, size) {
for (var x = 0, l = arr.length, arrD = []; x < l; x++) {
x % size === 0 ? arrD.push([arr[x]]) : arrD[arrD.length - 1].push(arr[x]);
}
return arrD;
}
var _ = chunk(["a", "b", "c", "d"], 2);
document.write(JSON.stringify(_));
Try this:
function chunk(arr, size) {
// Break it up.
var output = [];
var length = arr.length/size; // this is because each time you splice original array size reduces.
for (var x = 0; x < length; x++) {
if (arr.length > size) {
output.push(arr.splice([0], size));
} else {
output.push(arr.splice([0], arr.length));
}
}
return output;
}
console.log(chunk([0, 1, 2, 3, 4, 5], 2));
Your function isn't working because by using splice, you remove items from the array during the iteration, but you don't change the loop variable (x) accordingly.
A possible solution could be changing the for loop to while:
function chunk(arr, size) {
// Break it up.
var output = [];
while(arr.length > 0) {
if (arr.length >= size) {
output.push(arr.splice([0], size));
} else {
output.push(arr.splice([0], arr.length));
}
}
return output;
}
Try it this way:
function chunk(arr, size) {
// Break it up.
var output = [];
var yo = arr.length;
for (var x = 0; x < yo; x++) {
if (arr.length > size) {
output.push(arr.splice([0], size));
} else {
output.push(arr);
break;
}
}
return output;
}
console.log(chunk([0, 1, 2, 3, 4, 5], 2));
The issues were:
Array length was always changing as splice modifies the array itself.
arr.length > size should be the condition.
Fiddle
Another solution is:
function chunk(arr, size) {
var i, temparray, finalarray = [];
for (i=0; i<arr.length; i+=size) {
temparray = arr.slice(i, i+size);
finalarray.push(temparray);
}
return finalarray;
}
The problem
splice deletes elements from your array. Because of that, your array will automatically get smaller and smaller until no more elements are left.
This means your loop should stop when 0 < arr.length and only then. This also means you can completely remove your x variable.
Demo :
function chunk(arr, size) {
// Break it up.
var output = [];
for (; 0 < arr.length;) {
if (arr.length >= size) {
output.push(arr.splice(0, size));
} else {
output.push(arr.splice(0, arr.length));
}
}
return output;
}
var data = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M'];
document.body.innerHTML = '<pre>' +
'SIZE 3\n-------\n' +
JSON.stringify(chunk(data, 3), null, 2) +
'</pre>';
An alternative approach
It's better not to use splice, because it deletes all the data from your array. This means you can't eg. execute chunk twice or do anything else with your array after executing chunk.
A better approach, would be to use slice instead, which just copies a segment of your array and leaves the array intact.
Using slice, you can just use a classic for-loop, except that you increment isn't 1 but the size of your segments.
Demo :
function chunk(arr, size) {
var output = [];
var length = arr.length;
for (var x = 0, length = arr.length; x < length; x = x + size) {
output.push(arr.slice([x], x + size));
}
return output;
}
var data = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M'];
document.body.innerHTML =
'<pre>' +
'SIZE 2\n-------\n' +
JSON.stringify(chunk(data, 2), null, 2) +
"\n\n"+
'SIZE 3\n-------\n' +
JSON.stringify(chunk(data, 3), null, 2) +
"\n\n"+
'SIZE 4\n-------\n' +
JSON.stringify(chunk(data, 4), null, 2) +
"\n\n"+
'SIZE 5\n-------\n' +
JSON.stringify(chunk(data, 5), null, 2) +
"\n\n"+
'SIZE 6\n-------\n' +
JSON.stringify(chunk(data, 6), null, 2) +
"\n\n"+
'SIZE 7\n-------\n' +
JSON.stringify(chunk(data, 7), null, 2) +
'</pre>';
Here is a "one-liner" using recursion:
function chunk(a, s) {
return a.length ? [a.slice(0, s)].concat(chunk(a.slice(s), s)) : [];
}
document.write(JSON.stringify(
chunk(["a", "b", "c", "d"], 2)
));

Function in JS that returns a object with unique values in array and number of times they appear

I'am pretty new to JavaScript and i have this exercise that have been bugging me for a some hours now.
I want to write a Javascript function that expects an array which could contain string and/or numbers (as well as finite levels of nested arrays of strings and/or numbers), and returns a Javascript object which shows the total number of occurences of each unique values.
Something like this
var myArray = [ 1, 2, 1, 'a', [ 'd', 5, 6 ], 'A', 2, 'b', 1, 'd' ];
var myResult = myFunction( myArray );
Then it should return something like this
yourResult = {
1: 3,
2: 2,
'a': 1,
'd': 2,
5: 1,
6: 1,
'A': 1,
'b': 1,
}
So far what i have is this. I dont know how to create the object but this is not working at all. It ads all the values in the array
Array.prototype.contains = function(v) {
for(var i = 0; i < this.length; i++) {
if(this[i] === v) return true;
}
return false;
};
Array.prototype.unique = function() {
var arr = [];
for(var i = 0; i < this.length; i++) {
if(this[i] instanceof Array) {
for(var j = 0; i < this[i].length; j++){
if (!arr.contains(this[i][j])){
arr.push(this[i][j]);
}
}
}
if(!arr.contains(this[i])) {
arr.push(this[i]);
}
}
return arr;
}
var myArray = [1,3,4,2,1,[1,2,3,6],2,3,8];
var myResult = duplicates.unique();
console.log(myResult);
I would seperate it into 2 major problems:
1. Make the array members to be at one level (not nested).
2. Count repeats
The first one I solved with recursion, hope it's meet the requirements. The second is about counting instances..
Hope it's help
Fiddle example
var myArray = [ 1, 2, 1, 'a', [ 'd', 5, 6 ], 'A', 2, 'b', 1, 'd' ];
var myResult = myFunction( myArray );
console.log(myResult);
function myFunction(arr) {
var r = {};
for (var i=0 ; i < arr.length ; i++) {
if( Object.prototype.toString.call( arr[i] ) === '[object Array]' ) {
var sub = myFunction(arr[i]);
for (var attrname in sub) {
if (r[attrname])
r[attrname]++;
else {
r[attrname] = sub[attrname];
r[attrname] = 1;
}
}
}
else if (r[arr[i]])
r[arr[i]]++;
else
r[arr[i]] = 1;
}
return r;
}
An associative array is what you need to hold the result:
var associative_array={}
then you can use a function like this:
function add_to_as(value){ //Add element to the global associative array
if(associative_array[value]==undefined){
associative_array[value]=1;
}
else{
associative_array[value] +=1;//add one
}
}
function myFunction( mydata ){
for(var i = 0; i < mydata.length; i++) {
if(mydata[i] instanceof Array) { //recurse on sublists if any
myFunction(mydata[i])
}
else{
add_to_as(mydata[i]);
}
}
}
//To test the function
var myArray = [ 1, 2, 1, 'a', [ 'd', 5, 6 ], 'A', 2, 'b', 1, 'd' ];
myFunction(myArray);
console.log(associative_array);
Besides your code
you can put all the elements of your array to a second array containing all the elements of array and sub arrays. Then you can iterate over second array and find the occurrence of each element like this
var arr1 = [1, 2, 1, 'a', ['d', 5, 6], 'A', 2, 'b', 1, 'd'];
var arr = [];
var obj = {};
for (var i = 0; i < arr1.length; i++) {
if (arr1[i].length == undefined || arr1[i].length == 1) {
arr.push(arr1[i]);
}
else {
for (var j = 0; j < arr1[i].length; j++) {
arr.push(arr1[i][j]);
}
}
}
for (var i = 0, j = arr.length; i < j; i++) {
if (obj[arr[i]]) {
obj[arr[i]]++;
}
else {
obj[arr[i]] = 1;
}
}
console.log(obj);
DEMO
Updated:In case of nested arrays
var arr2 = [1, 2, 1, 'a', ['d', 5, 6,['d', 5, 6,['d', 5, 6]]], 'A', 2, 'b', 1, 'd'];
var arr = [];
var obj = {};
function singleArray(arr1) {
for (var i = 0; i < arr1.length; i++) {
if (arr1[i].length == undefined || arr1[i].length == 1) {
arr.push(arr1[i]);
}
else {
singleArray(arr1[i]);
}
}
}
singleArray(arr2);
for (var i = 0, j = arr.length; i < j; i++) {
if (obj[arr[i]]) {
obj[arr[i]]++;
}
else {
obj[arr[i]] = 1;
}
}
console.log(obj);
DEMO

Sort Object Containing Multiple Arrays: JavaScript [duplicate]

for hours i've been trying to figure out how to sort 2 array dependently.
Let's say I have 2 arrays.
First one:
array1 = ['zzzzz', 'aaaaaa', 'ccccc'];
and the second one:
array2 = [3, 7, 1];
I sort the first one with array1.sort(); and it becomes [aaaaaa, cccccc, zzzzzz]
now what I want is that the second one becomes [7, 1, 3]
I think it's quite simple but i'm trying to implement this in something a little more complex, im new and i keep mixing up things.
Thanks
I would "zip" them into one array of objects, then sort that with a custom sort callback, then "unzip" them back into the two arrays you wanted:
var array1 = ['zzzzz', 'aaaaaa', 'ccccc'],
array2 = [3, 7, 1],
zipped = [],
i;
for(i=0; i<array1.length; ++i) {
zipped.push({
array1elem: array1[i],
array2elem: array2[i]
});
}
zipped.sort(function(left, right) {
var leftArray1elem = left.array1elem,
rightArray1elem = right.array1elem;
return leftArray1elem === rightArray1elem ? 0 : (leftArray1elem < rightArray1elem ? -1 : 1);
});
array1 = [];
array2 = [];
for(i=0; i<zipped.length; ++i) {
array1.push(zipped[i].array1elem);
array2.push(zipped[i].array2elem);
}
alert('Sorted arrays:\n\narray1: ' + array1 + '\n\narray2: ' + array2);
Here's a working fiddle.
Here's a simple function that will do the trick:
function sortTogether(array1, array2) {
var merged = [];
for(var i=0; i<array1.length; i++) { merged.push({'a1': array1[i], 'a2': array2[i]}); }
merged.sort(function(o1, o2) { return ((o1.a1 < o2.a1) ? -1 : ((o1.a1 == o2.a1) ? 0 : 1)); });
for(var i=0; i<merged.length; i++) { array1[i] = merged[i].a1; array2[i] = merged[i].a2; }
}
Usage demo (fiddle here):
var array1 = ['zzzzz', 'aaaaaa', 'ccccc'];
var array2 = [3, 7, 1];
console.log('Before..: ',array1,array2);
sortTogether(array1, array2); // simply call the function
console.log('After...: ',array1,array2);
Output:
Before..: ["zzzzz", "aaaaaa", "ccccc"] [3, 7, 1]
After...: ["aaaaaa", "ccccc", "zzzzz"] [7, 1, 3]
Instead of two arrays of primitive types (strings, numbers) you can make an array of objects where one property of the object is string (containing "aaaaa", "cccccc", "zzzzzz") and another is number (7,1,3). This way you will have one array only, which you can sort by any property and the other property will remain in sync.
It just so happens I had some old code lying around that might do the trick:
function arrVirtualSortGetIndices(array,fnCompare){
var index=array.map(function(e,i,a){return i;});
fnCompare=fnCompare || defaultStringCompare;
var idxCompare=function (aa,bb){return fnCompare(array[aa],array[bb]);};
index.sort(idxCompare);
return index;
function defaultStringCompare(aa,bb){
if(aa<bb)return -1;
if(bb<aa)return 1;
return 0;
}
function defaultNumericalCompare(aa,bb){
return aa-bb;
}
}
function arrReorderByIndices(array,indices){
return array.map(
function(el,ix,ar){
return ar[indices[ix]];
}
);
}
var array1 = ['zzzzz', 'aaaaaa', 'ccccc'];
var array2 = [3, 7, 1];
var indices=arrVirtualSortGetIndices(array1);
var array2sorted=arrReorderByIndices(array2,indices);
array2sorted;
/*
7,1,3
*/
Sorry, I don't do 'fors'. At least not when I don't have to.
And fiddle.
Also, an alternative fiddle that sorts the results when given an array of objects like this:
given:
var list = [
{str:'zzzzz',value:3},
{str:'aaaaa',value:7},
{str:'ccccc',value:1}
];
outputs:
[
{str: "aaaaa", value: 7},
{str: "ccccc", value: 1},
{str: "zzzzz", value: 3}
]
Assumption:
The arrays are the same length (this is implied by your question)
the contents can be compared with > and < (true in your example, but I wanted to make it clear that it was assumed here)
So then we can use an insertion sort.
var value,len = array1.length;
for (i=0; i < len; i++) {
value = array1[i];
for (j=i-1; j > -1 && array1[j] > value; j--) {
array1[j+1] = array1[j];
array2[j+1] = array2[j];
}
items[j+1] = value;
}
Using a solution found here to find the new indices after sorting an array, you can apply those indices to array2 like so.
function sortWithIndices(toSort) {
for (var i = 0; i < toSort.length; i++) {
toSort[i] = [toSort[i], i];
}
toSort.sort(function(left, right) {
return left[0] < right[0] ? -1 : 1;
});
toSort.sortIndices = [];
for (var j = 0; j < toSort.length; j++) {
toSort.sortIndices.push(toSort[j][2]);
toSort[j] = toSort[j][0];
}
return toSort;
}
var array1 = ['zzzz', 'aaaa', 'cccc'];
var array2 = [3, 7, 1];
// calculate the indices of array1 after sorting. (attached to array1.sortIndices)
sortWithIndices(array1);
// the final array after applying the sorted indices from array1 to array2
var final = [];
// apply sorted indices to array2
for(var i = 0; i < array1.sortIndices.length; i++)
final[i] = array2[array1.sortIndices[i]];
// output results
alert(final.join(","));
JSFiddle Demo

How to count duplicate value in an array in javascript

Currently, I got an array like that:
var uniqueCount = Array();
After a few steps, my array looks like that:
uniqueCount = [a,b,c,d,d,e,a,b,c,f,g,h,h,h,e,a];
How can I count how many a,b,c are there in the array? I want to have a result like:
a = 3
b = 1
c = 2
d = 2
etc.
const counts = {};
const sampleArray = ['a', 'a', 'b', 'c'];
sampleArray.forEach(function (x) { counts[x] = (counts[x] || 0) + 1; });
console.log(counts)
Something like this:
uniqueCount = ["a","b","c","d","d","e","a","b","c","f","g","h","h","h","e","a"];
var count = {};
uniqueCount.forEach(function(i) { count[i] = (count[i]||0) + 1;});
console.log(count);
Use a simple for loop instead of forEach if you don't want this to break in older browsers.
I stumbled across this (very old) question. Interestingly the most obvious and elegant solution (imho) is missing: Array.prototype.reduce(...). All major browsers support this feature since about 2011 (IE) or even earlier (all others):
var arr = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
var map = arr.reduce(function(prev, cur) {
prev[cur] = (prev[cur] || 0) + 1;
return prev;
}, {});
// map is an associative array mapping the elements to their frequency:
console.log(map);
// prints {"a": 3, "b": 2, "c": 2, "d": 2, "e": 2, "f": 1, "g": 1, "h": 3}
EDIT:
By using the comma operator in an arrow function, we can write it in one single line of code:
var arr = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
var map = arr.reduce((cnt, cur) => (cnt[cur] = cnt[cur] + 1 || 1, cnt), {});
// map is an associative array mapping the elements to their frequency:
console.log(map);
// prints {"a": 3, "b": 2, "c": 2, "d": 2, "e": 2, "f": 1, "g": 1, "h": 3}
However, as this may be harder to read/understand, one should probably stick to the first version.
function count() {
array_elements = ["a", "b", "c", "d", "e", "a", "b", "c", "f", "g", "h", "h", "h", "e", "a"];
array_elements.sort();
var current = null;
var cnt = 0;
for (var i = 0; i < array_elements.length; i++) {
if (array_elements[i] != current) {
if (cnt > 0) {
document.write(current + ' comes --> ' + cnt + ' times<br>');
}
current = array_elements[i];
cnt = 1;
} else {
cnt++;
}
}
if (cnt > 0) {
document.write(current + ' comes --> ' + cnt + ' times');
}
}
count();
Demo Fiddle
You can use higher-order functions too to do the operation. See this answer
Simple is better, one variable, one function :)
const arr = ["a", "b", "c", "d", "d", "e", "a", "b", "c", "f", "g", "h", "h", "h", "e", "a"];
const counts = arr.reduce((acc, value) => ({
...acc,
[value]: (acc[value] || 0) + 1
}), {});
console.log(counts);
Single line based on reduce array function
const uniqueCount = ["a", "b", "c", "d", "d", "e", "a", "b", "c", "f", "g", "h", "h", "h", "e", "a"];
const distribution = uniqueCount.reduce((acum,cur) => Object.assign(acum,{[cur]: (acum[cur] || 0)+1}),{});
console.log(JSON.stringify(distribution,null,2));
// Initial array
let array = ['a', 'b', 'c', 'd', 'd', 'e', 'a', 'b', 'c', 'f', 'g', 'h', 'h', 'h', 'e', 'a'];
// Unique array without duplicates ['a', 'b', ... , 'h']
let unique = [...new Set(array)];
// This array counts duplicates [['a', 3], ['b', 2], ... , ['h', 3]]
let duplicates = unique.map(value => [value, array.filter(str => str === value).length]);
Nobody responding seems to be using the Map() built-in for this, which tends to be my go-to combined with Array.prototype.reduce():
const data = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
const result = data.reduce((a, c) => a.set(c, (a.get(c) || 0) + 1), new Map());
console.log(...result);
N.b., you'll have to polyfill Map() if wanting to use it in older browsers.
I think this is the simplest way how to count occurrences with same value in array.
var a = [true, false, false, false];
a.filter(function(value){
return value === false;
}).length
You can solve it without using any for/while loops ou forEach.
function myCounter(inputWords) {
return inputWords.reduce( (countWords, word) => {
countWords[word] = ++countWords[word] || 1;
return countWords;
}, {});
}
Hope it helps you!
It is simple in javascript using array reduce method:
const arr = ['a','d','r','a','a','f','d'];
const result = arr.reduce((json,val)=>({...json, [val]:(json[val] | 0) + 1}),{});
console.log(result)
//{ a:3,d:2,r:1,f:1 }
You can have an object that contains counts. Walk over the list and increment the count for each element:
var counts = {};
uniqueCount.forEach(function(element) {
counts[element] = (counts[element] || 0) + 1;
});
for (var element in counts) {
console.log(element + ' = ' + counts[element]);
}
// new example.
var str= [20,1,-1,2,-2,3,3,5,5,1,2,4,20,4,-1,-2,5];
function findOdd(para) {
var count = {};
para.forEach(function(para) {
count[para] = (count[para] || 0) + 1;
});
return count;
}
console.log(findOdd(str));
const obj = {};
const uniqueCount = [ 'a', 'b', 'c', 'd', 'e', 'a', 'b', 'c', 'f', 'g', 'h', 'h', 'h', 'e', 'a' ];
for (let i of uniqueCount) obj[i] ? obj[i]++ : (obj[i] = 1);
console.log(obj);
You can do something like that:
uniqueCount = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
var map = new Object();
for(var i = 0; i < uniqueCount.length; i++) {
if(map[uniqueCount[i]] != null) {
map[uniqueCount[i]] += 1;
} else {
map[uniqueCount[i]] = 1;
}
}
now you have a map with all characters count
uniqueCount = ["a","b","a","c","b","a","d","b","c","f","g","h","h","h","e","a"];
var count = {};
uniqueCount.forEach((i) => { count[i] = ++count[i]|| 1});
console.log(count);
Duplicates in an array containing alphabets:
var arr = ["a", "b", "a", "z", "e", "a", "b", "f", "d", "f"],
sortedArr = [],
count = 1;
sortedArr = arr.sort();
for (var i = 0; i < sortedArr.length; i = i + count) {
count = 1;
for (var j = i + 1; j < sortedArr.length; j++) {
if (sortedArr[i] === sortedArr[j])
count++;
}
document.write(sortedArr[i] + " = " + count + "<br>");
}
Duplicates in an array containing numbers:
var arr = [2, 1, 3, 2, 8, 9, 1, 3, 1, 1, 1, 2, 24, 25, 67, 10, 54, 2, 1, 9, 8, 1],
sortedArr = [],
count = 1;
sortedArr = arr.sort(function(a, b) {
return a - b
});
for (var i = 0; i < sortedArr.length; i = i + count) {
count = 1;
for (var j = i + 1; j < sortedArr.length; j++) {
if (sortedArr[i] === sortedArr[j])
count++;
}
document.write(sortedArr[i] + " = " + count + "<br>");
}
simplified sheet.js answare
var counts = {};
var aarr=['a','b','a'];
aarr.forEach(x=>counts[x]=(counts[x] || 0)+1 );
console.log(counts)
CODE:
function getUniqueDataCount(objArr, propName) {
var data = [];
if (Array.isArray(propName)) {
propName.forEach(prop => {
objArr.forEach(function(d, index) {
if (d[prop]) {
data.push(d[prop]);
}
});
});
} else {
objArr.forEach(function(d, index) {
if (d[propName]) {
data.push(d[propName]);
}
});
}
var uniqueList = [...new Set(data)];
var dataSet = {};
for (var i = 0; i < uniqueList.length; i++) {
dataSet[uniqueList[i]] = data.filter(x => x == uniqueList[i]).length;
}
return dataSet;
}
Snippet
var data= [
{day:'Friday' , name: 'John' },
{day:'Friday' , name: 'John' },
{day:'Friday' , name: 'Marium' },
{day:'Wednesday', name: 'Stephanie' },
{day:'Monday' , name: 'Chris' },
{day:'Monday' , name: 'Marium' },
];
console.log(getUniqueDataCount(data, ['day','name']));
function getUniqueDataCount(objArr, propName) {
var data = [];
if (Array.isArray(propName)) {
propName.forEach(prop => {
objArr.forEach(function(d, index) {
if (d[prop]) {
data.push(d[prop]);
}
});
});
} else {
objArr.forEach(function(d, index) {
if (d[propName]) {
data.push(d[propName]);
}
});
}
var uniqueList = [...new Set(data)];
var dataSet = {};
for (var i = 0; i < uniqueList.length; i++) {
dataSet[uniqueList[i]] = data.filter(x => x == uniqueList[i]).length;
}
return dataSet;
}
var uniqueCount = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
// here we will collect only unique items from the array
var uniqueChars = [];
// iterate through each item of uniqueCount
for (i of uniqueCount) {
// if this is an item that was not earlier in uniqueCount,
// put it into the uniqueChars array
if (uniqueChars.indexOf(i) == -1) {
uniqueChars.push(i);
}
}
// after iterating through all uniqueCount take each item in uniqueChars
// and compare it with each item in uniqueCount. If this uniqueChars item
// corresponds to an item in uniqueCount, increase letterAccumulator by one.
for (x of uniqueChars) {
let letterAccumulator = 0;
for (i of uniqueCount) {
if (i == x) {letterAccumulator++;}
}
console.log(`${x} = ${letterAccumulator}`);
}
var testArray = ['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a'];
var newArr = [];
testArray.forEach((item) => {
newArr[item] = testArray.filter((el) => {
return el === item;
}).length;
})
console.log(newArr);
Using this solution you can now get map of repeated items:
Str= ['a','b','c','d','d','e','a','h','e','a'];
var obj= new Object();
for(var i = 0; i < Str.length; i++) {
if(obj[Str[i]] != null) {
obj[Str[i]] += 1;
} else {
obj[Str[i]] = 1;
}
}
console.log(obj);
Steps : first check if in accumulator has the current value or not if not ,than for that particular value set the count as 1 and in else condition ,if value alreadt exist in accumulator the simple increment the count.
const testarr = [1,2,1,3,1,2,4];
var count = testarr.reduce((acc,currentval)=>{
if(acc[currentval]){ acc[currentval] = ++acc[currentval]; }else{ acc[currentval] = 1; } return acc; },{})
console.log(count);
use forEach() method for convinience
var uniqueCount="a","b","c","d","d","e","a","b","c","f","g","h","h","h","e","a"];
var count=0;
var obj={};
uniqueCount.forEach((i,j)=>{
count=0;
var now=i;
uniqueCount.forEach((i,j)=>{
if(now==uniqueCount[j]){
count++;
obj[i]=count;
}
});
});
console.log(obj);
A combination of good answers:
var count = {};
var arr = ['a', 'b', 'c', 'd', 'd', 'e', 'a', 'b', 'c', 'f', 'g', 'h', 'h', 'h', 'e', 'a'];
var iterator = function (element) {
count[element] = (count[element] || 0) + 1;
}
if (arr.forEach) {
arr.forEach(function (element) {
iterator(element);
});
} else {
for (var i = 0; i < arr.length; i++) {
iterator(arr[i]);
}
}
Hope it's helpful.
By using array.map we can reduce the loop, see this on jsfiddle
function Check(){
var arr = Array.prototype.slice.call(arguments);
var result = [];
for(i=0; i< arr.length; i++){
var duplicate = 0;
var val = arr[i];
arr.map(function(x){
if(val === x) duplicate++;
})
result.push(duplicate>= 2);
}
return result;
}
To Test:
var test = new Check(1,2,1,4,1);
console.log(test);
var string = ['a','a','b','c','c','c','c','c','a','a','a'];
function stringCompress(string){
var obj = {},str = "";
string.forEach(function(i) {
obj[i] = (obj[i]||0) + 1;
});
for(var key in obj){
str += (key+obj[key]);
}
console.log(obj);
console.log(str);
}stringCompress(string)
/*
Always open to improvement ,please share
*/
Create a file for example demo.js and run it in console with node demo.js and you will get occurrence of elements in the form of matrix.
var multipleDuplicateArr = Array(10).fill(0).map(()=>{return Math.floor(Math.random() * Math.floor(9))});
console.log(multipleDuplicateArr);
var resultArr = Array(Array('KEYS','OCCURRENCE'));
for (var i = 0; i < multipleDuplicateArr.length; i++) {
var flag = true;
for (var j = 0; j < resultArr.length; j++) {
if(resultArr[j][0] == multipleDuplicateArr[i]){
resultArr[j][1] = resultArr[j][1] + 1;
flag = false;
}
}
if(flag){
resultArr.push(Array(multipleDuplicateArr[i],1));
}
}
console.log(resultArr);
You will get result in console as below:
[ 1, 4, 5, 2, 6, 8, 7, 5, 0, 5 ] . // multipleDuplicateArr
[ [ 'KEYS', 'OCCURENCE' ], // resultArr
[ 1, 1 ],
[ 4, 1 ],
[ 5, 3 ],
[ 2, 1 ],
[ 6, 1 ],
[ 8, 1 ],
[ 7, 1 ],
[ 0, 1 ] ]
Quickest way:
Сomputational complexity is O(n).
function howMuchIsRepeated_es5(arr) {
const count = {};
for (let i = 0; i < arr.length; i++) {
const val = arr[i];
if (val in count) {
count[val] = count[val] + 1;
} else {
count[val] = 1;
}
}
for (let key in count) {
console.log("Value " + key + " is repeated " + count[key] + " times");
}
}
howMuchIsRepeated_es5(['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a']);
The shortest code:
Use ES6.
function howMuchIsRepeated_es6(arr) {
// count is [ [valX, count], [valY, count], [valZ, count]... ];
const count = [...new Set(arr)].map(val => [val, arr.join("").split(val).length - 1]);
for (let i = 0; i < count.length; i++) {
console.log(`Value ${count[i][0]} is repeated ${count[i][1]} times`);
}
}
howMuchIsRepeated_es6(['a','b','c','d','d','e','a','b','c','f','g','h','h','h','e','a']);
var arr = ['a','d','r','a','a','f','d'];
//call function and pass your array, function will return an object with array values as keys and their count as the key values.
duplicatesArr(arr);
function duplicatesArr(arr){
var obj = {}
for(var i = 0; i < arr.length; i++){
obj[arr[i]] = [];
for(var x = 0; x < arr.length; x++){
(arr[i] == arr[x]) ? obj[arr[i]].push(x) : '';
}
obj[arr[i]] = obj[arr[i]].length;
}
console.log(obj);
return obj;
}

Categories

Resources