Group identical values in array - javascript

I have an array that has some values inside, and I wish to return another array that has the value grouped in to their own arrays.
So the result I am trying to achieve is something like this:
var arr = [1,1,2,2,2,3,3,4,4,4,4,5,6]
var groupedArr =[[1,1],[2,2,2],[3,3],[4,4,4,4],[5],[6]]

This proposal works with Array#reduce for sorted arrays.
var arr = [1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 6],
groupedArr = arr.reduce(function (r, a, i) {
if (!i || a !== r[r.length - 1][0]) {
return r.concat([[a]]);
}
r[r.length - 1].push(a);
return r;
}, []);
document.write('<pre>' + JSON.stringify(groupedArr, 0, 4) + '</pre>');

Here you go. By the way, this works with unsorted array as well.
var arr = [1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 6]
var grpdArr = [];
while(arr.length > 0){
var item = arr[0];
grpdArr.push(arr.filter(function(val) {
return val === item;
}));
arr = arr.filter(function(val){return val!==item});
}
//console.log(arr, grpdArr);
Well this should do. Pretty straight forward..,
You get the elements and then remove them.

With forEach and temporary array
var arr = [1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 6];
var temp = [];
var res = [];
arr.forEach(function(e) {
if (temp.slice(-1) == e) temp.push(e);
else {
temp = [e];
res.push(temp);
}
});
document.write(JSON.stringify(res));

This may not be the most optimal version but should do. This also works for unsorted arrays.
function abc(arr) {
var newObj = new Object();
for (var i in arr) {
if (typeof newObj[arr[i]] == 'undefined') {
newObj[arr[i]] = new Array();
}
newObj[arr[i]].push(arr[i]);
}
var groupedArr = new Array();
for (i in newObj) {
groupedArr.push(newObj[i]);
}
return groupedArr;
}
console.log(abc([1, 1, 2, 2, 3, 3, 3, 4, 1]));

This is the most straightforward in my mind:
var arr = [1,1,2,2,2,3,3,4,4,4,4,5,6];
var grouped = {};
var groupedArr = [];
//accumulate the values in an object, each key is an array
for (var i = 0; i < arr.length; i++) {
if (!grouped[arr[i]]) grouped[arr[i]] = [];
grouped[arr[i]].push(arr[i]);
}
//loop through all the keys in the object and push the arrays to the master array
var keys = Object.keys(grouped);
for (var i = 0; i < keys.length; i++) {
groupedArr.push(grouped[keys[i]]);
}
console.log(groupedArr);

I think you could use the code below:
var arr = [1,1,2,2,2,3,3,4,4,4,4,5,6]
var groupedArray = [];
var temp = arr.sort();
var tempArray = [arr[0]];
for(var i = 0; i < temp.length - 1; ++i){
if(temp[i] == temp[i + 1]){
tempArray.push(temp[i + 1]);
}else{
groupedArray.push(tempArray);
tempArray = [temp[i + 1]];
}
}
groupedArray.push(tempArray);
Now the groupedArray will contain the Result

Related

I am doing this challenge at Leet Code where you should sort array and delete all zeros and it always keeps one zero?

nums1 = [1,2,3,0,0,0]
nums2 = [2,5,6]
var merge = function(nums1,nums2) {
let deletezeros = function(numi){
for(let i = 0; i < numi.length; i++){
if(numi[i] == 0){
numi.splice(i, 1)
}
}
}
deletezeros(nums1)
deletezeros(nums2)
let result = nums1.concat(nums2)
result.sort()
return result
};
let a = merge(nums1,nums2)
console.log(a)
result is
[
0, 1, 2, 2,
3, 5, 6
]
Decrement i after calling splice:
nums1 = [1, 2, 3, 0, 0, 0]
nums2 = [2, 5, 6]
var merge = function(nums1, nums2) {
let deletezeros = function(numi) {
for (let i = 0; i < numi.length; i++) {
if (numi[i] == 0) {
numi.splice(i, 1)
i--;
}
}
}
deletezeros(nums1)
deletezeros(nums2)
let result = nums1.concat(nums2)
result.sort()
return result
};
let a = merge(nums1, nums2)
console.log(a)

get List of values exist more than once in array [duplicate]

This question already has answers here:
How to keep Duplicates of an Array
(4 answers)
Closed 5 years ago.
I have to get a list of values that exist more than once in an array.
This is current code , but as you can see it's too complicated.
var arr = [1, 2, 3, 4, 2, 3];
var flag = {}
var exist2arr = [];
for(var i = 0; i < arr.length; i++){
for(var j = 0 ; j < arr.length; j ++){
if(i !=j && arr[i] == arr[j]){
if(!flag[arr[i]])
exist2arr.push(arr[i]);
flag[arr[i]] = 1;
}
}
}
console.log(exist2arr);
Is there any other way (simple code using javascript built-in function) to achieve this? Any kind of help appreciate.
You could filter the array based on values who's first and current indexes are not equal then run that array through a Set
const arr = [1, 2, 3, 4, 2, 3, 2, 3, 2, 3, 2, 3]; // added in some extras
const filtered = arr.filter((v, i) => arr.indexOf(v) !== i)
const unique = new Set(filtered)
console.info(Array.from(unique)) // using Array.from so it can be logged
var arr = [1, 2, 3, 4, 2, 3];
var o = arr.reduce((o, n) => {
n in o ? o[n] += 1 : o[n] = 1;
return o;
}, {});
var res = Object.keys(o).filter(k => o[k] > 1);
console.log(res);
A bit hacky, but short and O(n):
var arr = [1, 2, 3, 4, 2, 3, 2, 2]
var a = arr.reduce((r, v) => ((r[v + .1] = r[v + .1] + 1 || 1) - 2 || r.push(v), r), [])
console.log( a ) // [2,3]
console.log({ ...a }) // to show the "hidden" items
console.log({ ...a.slice() }) // .slice() can be used to remove the extra items
It could be done like:
function timesInArray(v, a){
var n = 0;
for(var i=0,l=a.length; i<l; i++){
if(a[i] === v){
n++;
}
}
return n;
}
function dups(dupArray, num){
var n = num === undefined ? 2 : num;
var r = [];
for(var i=0,d,l=dupArray.length; i<l; i++){
d = dupArray[i];
if(!timesInArray(d, r) && timesInArray(d, dupArray) >= n){
r.push(d);
}
}
return r;
}
var testArray = [4, 5, 2, 5, 7, 7, 2, 1, 3, 7, 7, 7, 25, 77, 4, 2];
console.log(dups(testArray)); console.log(dups(testArray, 3));

Compare two arrays of numbers and return array of highest values

What would be the most efficient way to compare two arrays of integers and return a unique array of the higher corresponding integers in each array?
(can use lodash)
ex:
var arr1 = [0, 1, 2, 1, 0];
var arr2 = [1, 0, 0, 3, 0];
// result = [1, 1, 2, 3, 0];
Here's my first, less efficient method:
var arr1 = [0, 1, 2, 1, 0];
var arr2 = [1, 0, 0, 3, 0];
arr1.map(function (item, i) {
return Math.max(item, arr2[i])
}); // [1, 1, 2, 3, 0]
What it lacks in speed, it gains in beauty!
Or for you ES6 boverers:
var arr1 = [0, 1, 2, 1, 0];
var arr2 = [1, 0, 0, 3, 0];
arr1.map((item, i) => Math.max(item, arr2[i])); // [1, 1, 2, 3, 0]
function selectHighestValues (arr1, arr2) {
var maxLength = Math.max(arr1.length, arr2.length);
var _arr = [];
for (var i = 0; i < maxLength; i++) {
if (arr1[i] && arr2[i]) {
_arr[i] = Math.max(arr1[i], arr2[i]);
} else if (arr1[i]) {
_arr[i] = arr1[i];
} else {
_arr[i] = arr2[i];
}
}
return _arr;
}
With splicing longest array and concatenation:
function selectHighestValues (arr1, arr2) {
var minLength = Math.min(arr1.length, arr2.length);
var maxLength = Math.max(arr1.length, arr2.length);
var longestArrayIndex = arr1.length > arr2.length ? 0 : 1;
var _arr = [];
for (var i = 0; i < minLength; i++) {
_arr[i] = Math.max(arr1[i], arr2[i]);
}
if (maxLength > minLength) {
var sliced = Array.prototype.slice.call(arguments[longestArrayIndex], minLength, maxLength);
_arr = Array.prototype.concat.call(_arr, sliced);
}
return _arr;
}
Brute force!
var arr1 = [0, 1, 2, 1, 0];
var arr2 = [1, 0, 0, 3, 0];
var result = [];
for(var i = 0; i < arr1.length; i++) {
if (arr1[i] > arr2[i]) {
result.push(arr1[i]);
} else {
result.push(arr2[i]);
}
}
_.zipWith(arr1, arr2, function(el1, el2) {
return (el1 > el2 ? el1 : el2);
});
_.zipWith() is only in lodash 3.x I believe.
Using zip(), map(), and max():
_.map(_.zip(arr1, arr2), _.ary(_.max, 1));

How to get common value from 4 different array with javascript

I have below arrow and I want to get common value from all four array. I have try below code and it's working but not the correct way I want. Instead of coming [2, 3] in new array it showing other value which are common at least in two or three array.
Fiddle Demo
My Code
var a = [11, 2, 3, 4],
b = [2, 6, 3, 5],
c = [4, 2, 20, 3],
d = [34, 2, 21, 5, 3],
result = [],
common = [];
function findCommon () {
for(var i = 0; i < arguments.length; i++){
var garr = arguments[i];
result = result.concat(arguments[i]);
};
}
findCommon(a,b,c,d);
var sorted_arr = result.sort();
for(var i = 0; i< result.length-1; i++){
if(result[i+1] == sorted_arr[i]){
common.push(result[i]);
}
};
alert(common); //[2, 2, 2, 3, 3, 4, 5]
You could use arrays as the values of an object, and use the numbers as the keys. It makes it easy to count the numbers then. Note, this code is also future proof, so that if you want fewer or more arrays to test, this will let you. It also de-dupes the individual arrays, so numbers within each are only counted once to prevent errors.
function findCommon() {
var obj = {};
var out = [];
var result = [];
// convert arguments to a proper array
var args = [].slice.call(arguments);
var len = args.length;
for (var i = 0, l = len; i < l; i++) {
// grab a de-duped array and and concatenate it
// http://stackoverflow.com/a/9229821/1377002
var unique = args[i].filter(function(item, pos) {
return args[i].indexOf(item) == pos;
});
result = result.concat(unique);
}
for (var i = 0, l = result.length; i < l; i++) {
var el = result[i];
// if the object key doesn't exist, create an array
// as the value; add the number to the array
if (!obj[el]) obj[el] = [];
obj[el].push(el);
}
for (var p in obj) {
// if the array length equals the original length of
// the number of arrays added to the function
// add it to the output array, as an integer
if (obj[p].length === len) out.push(+p);
}
return out;
}
findCommon(a, b, c, d); // [2]
In addition, this will find all multiple keys, so if you replace the 5 in d as 3, the result will be [2, 3].
DEMO which uses 4 arrays, multiple hits
DEMO which uses 5 arrays
Try this:
function findCommon()
{
var common=[];
for(i=0; i<a.length; i++)
{
if(b.indexOf(i) != -1 && c.indexOf(i) != -1 && d.indexOf(i) != -1)
{
common.push(i);
}
}
return common;
}
This will return array of common values between all four arrays. Here is the working fiddle.
Assuming you want something generic for X arrays and we are talking about integers this sounds to me like some bucket business.
var a = [11, 2, 3, 4],
b = [2, 6, 3, 5],
c = [4, 2, 20, 3],
d = [34, 2, 21, 5];
function findCommon()
{
var bucket = [];
var maxVal = 0;
var minVal = 0;
for(var i = 0; i < arguments.length; i++)
{
for(var j = 0 ; j < arguments[i].length ; j++)
{
var val = arguments[i][j];
bucket[val] = bucket[val] + 1 || 1;
if(val > maxVal)
{
maxVal = val;
}
else if(val < minVal)
{
minVal = val;
}
}
}
var retVal = 0;
var maxTimes = 0;
for(var i = minVal ; i <= maxVal ; i++)
{
var val = bucket[i];
if(val > maxTimes)
{
maxTimes = val;
retVal = i;
}
}
return retVal;
}
console.log(findCommon(a,b,c,d));
JSFIDDLE.
You cna use indexOf to resolve that:
array.indexOf(element) >=0 // it means that element is in array
or
array.indexOf(element) != -1
When you would be using jQuery, thre is a shorter version:
$.inArray(value, array)
More fancy way, would be to use filter (Filter):
function hasElement(element, index, array) {
return element.indexOf(i) >= 0;
}
filtered = [a,b,c,d].filter(hasElement);
filtered.length === 4
This Try,
will find the common number with number of times it repeated.
var a = [11, 2, 3, 4],
b = [2, 6, 3, 5],
c = [4, 2, 20, 3],
d = [34, 2, 21, 5],
result = [],
common = [];
var all = a.concat(b).concat(c).concat(d);
var commonNum=0;
var largestCounter=0
for(var i = 0; i< all.length-1; i++){
var counter=0;
if(a.indexOf(all[i])>-1) counter+=1;
if(b.indexOf(all[i])>-1) counter+=1;
if(c.indexOf(all[i])>-1) counter+=1;
if(d.indexOf(all[i])>-1) counter+=1;
if(counter>largestCounter)
{largestCounter = counter;
commonNum = all[i];
}
};
alert(commonNum+" with count " + largestCounter);

Convert simple array into two-dimensional array (matrix)

Imagine I have an array:
A = Array(1, 2, 3, 4, 5, 6, 7, 8, 9);
And I want it to convert into 2-dimensional array (matrix of N x M), for instance like this:
A = Array(Array(1, 2, 3), Array(4, 5, 6), Array(7, 8, 9));
Note, that rows and columns of the matrix is changeable.
Something like this?
function listToMatrix(list, elementsPerSubArray) {
var matrix = [], i, k;
for (i = 0, k = -1; i < list.length; i++) {
if (i % elementsPerSubArray === 0) {
k++;
matrix[k] = [];
}
matrix[k].push(list[i]);
}
return matrix;
}
Usage:
var matrix = listToMatrix([1, 2, 3, 4, 4, 5, 6, 7, 8, 9], 3);
// result: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
You can use the Array.prototype.reduce function to do this in one line.
ECMAScript 6 style:
myArr.reduce((rows, key, index) => (index % 3 == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows, []);
"Normal" JavaScript:
myArr.reduce(function (rows, key, index) {
return (index % 3 == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows;
}, []);
You can change the 3 to whatever you want the number of columns to be, or better yet, put it in a reusable function:
ECMAScript 6 style:
const toMatrix = (arr, width) =>
arr.reduce((rows, key, index) => (index % width == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows, []);
"Normal" JavaScript:
function toMatrix(arr, width) {
return arr.reduce(function (rows, key, index) {
return (index % width == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows;
}, []);
}
This code is generic no need to worry about size and array, works universally
function TwoDimensional(arr, size)
{
var res = [];
for(var i=0;i < arr.length;i = i+size)
res.push(arr.slice(i,i+size));
return res;
}
Defining empty array.
Iterate according to the size so we will get specified chunk.That's why I am incrementing i with size, because size can be 2,3,4,5,6......
Here, first I am slicing from i to (i+size) and then I am pushing it to empty array res.
Return the two-dimensional array.
The cleanest way I could come up with when stumbling across this myself was the following:
const arrayToMatrix = (array, columns) => Array(Math.ceil(array.length / columns)).fill('').reduce((acc, cur, index) => {
return [...acc, [...array].splice(index * columns, columns)]
}, [])
where usage would be something like
const things = [
'item 1', 'item 2',
'item 1', 'item 2',
'item 1', 'item 2'
]
const result = arrayToMatrix(things, 2)
where result ends up being
[
['item 1', 'item 2'],
['item 1', 'item 2'],
['item 1', 'item 2']
]
How about something like:
var matrixify = function(arr, rows, cols) {
var matrix = [];
if (rows * cols === arr.length) {
for(var i = 0; i < arr.length; i+= cols) {
matrix.push(arr.slice(i, cols + i));
}
}
return matrix;
};
var a = [0, 1, 2, 3, 4, 5, 6, 7];
matrixify(a, 2, 4);
http://jsfiddle.net/andrewwhitaker/ERAUs/
Simply use two for loops:
var rowNum = 3;
var colNum = 3;
var k = 0;
var dest = new Array(rowNum);
for (i=0; i<rowNum; ++i) {
var tmp = new Array(colNum);
for (j=0; j<colNum; ++j) {
tmp[j] = src[k];
k++;
}
dest[i] = tmp;
}
function matrixify( source, count )
{
var matrixified = [];
var tmp;
// iterate through the source array
for( var i = 0; i < source.length; i++ )
{
// use modulous to make sure you have the correct length.
if( i % count == 0 )
{
// if tmp exists, push it to the return array
if( tmp && tmp.length ) matrixified.push(tmp);
// reset the temporary array
tmp = [];
}
// add the current source value to the temp array.
tmp.push(source[i])
}
// return the result
return matrixified;
}
If you want to actually replace an array's internal values, I believe you can call the following:
source.splice(0, source.length, matrixify(source,3));
This a simple way to convert an array to a two-dimensional array.
function twoDarray(arr, totalPerArray) {
let i = 0;
let twoDimension = []; // Store the generated two D array
let tempArr = [...arr]; // Avoid modifying original array
while (i < arr.length) {
let subArray = []; // Store 2D subArray
for (var j = 0; j < totalPerArray; j++) {
if (tempArr.length) subArray.push(tempArr.shift());
}
twoDimension[twoDimension.length] = subArray;
i += totalPerArray;
}
return twoDimension;
}
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
twoDarray(arr, 3); // [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
function changeDimension(arr, size) {
var arrLen = arr.length;
var newArr = [];
var count=0;
var tempArr = [];
for(var i=0; i<arrLen; i++) {
count++;
tempArr.push(arr[i]);
if (count == size || i == arrLen-1) {
newArr.push(tempArr);
tempArr = [];
count = 0;
}
}
return newArr;
}
changeDimension([0, 1, 2, 3, 4, 5], 4);
function matrixify(array, n, m) {
var result = [];
for (var i = 0; i < n; i++) {
result[i] = array.splice(0, m);
}
return result;
}
a = matrixify(a, 3, 3);
function chunkArrToMultiDimArr(arr, size) {
var newArray = [];
while(arr.length > 0)
{
newArray.push(arr.slice(0, size));
arr = arr.slice(size);
}
return newArray;
}
//example - call function
chunkArrToMultiDimArr(["a", "b", "c", "d"], 2);
you can use push and slice like this
var array = [1,2,3,4,5,6,7,8,9] ;
var newarray = [[],[]] ;
newarray[0].push(array) ;
console.log(newarray[0]) ;
output will be
[[1, 2, 3, 4, 5, 6, 7, 8, 9]]
if you want divide array into 3 array
var array = [1,2,3,4,5,6,7,8,9] ;
var newarray = [[],[]] ;
newarray[0].push(array.slice(0,2)) ;
newarray[1].push(array.slice(3,5)) ;
newarray[2].push(array.slice(6,8)) ;
instead of three lines you can use splice
while(array.length) newarray.push(array.splice(0,3));
const x: any[] = ['abc', 'def', '532', '4ad', 'qwe', 'hf', 'fjgfj'];
// number of columns
const COL = 3;
const matrix = array.reduce((matrix, item, index) => {
if (index % COL === 0) {
matrix.push([]);
}
matrix[matrix.length - 1].push(item);
return matrix;
}, [])
console.log(matrix);
Using the Array grouping proposal (currently stage 3), you can now also do something like the following:
function chunkArray(array, perChunk) {
return Object.values(array.group((_, i) => i / perChunk | 0));
}
See also the MDN documentation for Array.prototype.group().
Simplest way with ES6 using Array.from()
const matrixify = (arr, size) =>
Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
arr.slice(i * size, i * size + size));
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] ;
console.log(matrixify(list, 3));
Another stab at it,
Creating an empty matrix (Array of row arrays)
Iterating arr and assigning to matching rows
function arrayToMatrix(arr, wantedRows) {
// create a empty matrix (wantedRows Array of Arrays]
// with arr in scope
return new Array(wantedRows).fill(arr)
// replace with the next row from arr
.map(() => arr.splice(0, wantedRows))
}
// Initialize arr
arr = new Array(16).fill(0).map((val, i) => i)
// call!!
console.log(arrayToMatrix(arr, 4));
// Trying to make it nice
const arrToMat = (arr, wantedRows) => new Array(wantedRows).fill(arr)
.map(() => arr.splice(0, wantedRows))
(like in: this one)
(and: this one from other thread)
MatArray Class?
Extending an Array to add to a prototype, seems useful, it does need some features to complement the Array methods, maybe there is a case for a kind of MatArray Class? also for multidimensional mats and flattening them, maybe, maybe not..
1D Array convert 2D array via rows number:
function twoDimensional(array, row) {
let newArray = [];
let arraySize = Math.floor(array.length / row);
let extraArraySize = array.length % row;
while (array.length) {
if (!!extraArraySize) {
newArray.push(array.splice(0, arraySize + 1));
extraArraySize--;
} else {
newArray.push(array.splice(0, arraySize));
}
}
return newArray;
}
function twoDimensional(array, row) {
let newArray = [];
let arraySize = Math.floor(array.length / row);
let extraArraySize = array.length % row;
while (array.length) {
if (!!extraArraySize) {
newArray.push(array.splice(0, arraySize + 1));
extraArraySize--;
} else {
newArray.push(array.splice(0, arraySize));
}
}
return newArray;
}
console.log(twoDimensional([1,2,3,4,5,6,7,8,9,10,11,12,13,14], 3))
Short answer use:
const gridArray=(a,b)=>{const d=[];return a.forEach((e,f)=>{const
h=Math.floor(f/b);d[h]=d[h]||[],d[h][f%b]=a[f]}),d};
Where:
a: is the array
b: is the number of columns
An awesome repository here .
api : masfufa.js
sample : masfufa.html
According to that sample , the following snippet resolve the issue :
jsdk.getAPI('my');
var A=[1, 2, 3, 4, 5, 6, 7, 8, 9];
var MX=myAPI.getInstance('masfufa',{data:A,dim:'3x3'});
then :
MX.get[0][0] // -> 1 (first)
MX.get[2][2] // ->9 (last)

Categories

Resources