How to get multiple indexes of array element - javascript

indexOf() gives the only one index of the matched element but how we find all indexes of matched element in JavaScript?

I would do it as follows;
Array.prototype.indicesOf = function(x){
return this.reduce((p,c,i) => c === x ? p.concat(i) : p ,[]);
};
var arr = [1,2,3,4,1,8,7,6,5];
console.log(arr.indicesOf(1));
console.log(arr.indicesOf(5));
console.log(arr.indicesOf(42));

Array.prototype.indexesOf = function(el) {
var ret = [];
var ix = 0;
while (true) {
ix = this.indexOf(el, ix);
if (ix === -1) break;
ret.push(ix);
}
return ret;
};
and then
[1,2,3,1].indexesOf(1)
should return [0,3].

Related

Fold a multi-dimensional array n:m in JavaScript [duplicate]

I have an Array. It contains several subgroups. Example:
let mainArray=[50,51,52,53,54,511,512,513,514,521,522,523,524,525,526,527]
I want to divide that main array into sub-arrays.For example
sub1 =[50,51,52,53,54]
sub2 =[511,512,513,514]
sub3 =[521,522,523,524,525,526,527]
Can you help me?
Use the Array reduce function :
let mainArray=[50,51,52,53,54,511,512,513,514,521,522,523,524,525,526,527];
let groups = mainArray.reduce (
(grps, el, i, main) => ((el === main[i-1] + 1 ? grps[0].push (el)
: grps.unshift ([el])), grps), []);
[sub3, sub2, sub1] = groups;
console.log (sub1, sub2, sub3);
This will create an Array of Subarays:
const arr = [50,51,52,53,54, 511,512,513,514, 521,522,523,524,525,526,527];
let newArr = [];
let temp = [arr[0]];
for (let index = 1; index < arr.length; index++) {
if (arr[index] == arr[index - 1] + 1) {
temp.push(arr[index]);
} else {
newArr.push(temp);
temp = [];
}
if (index == arr.length - 1) {
newArr.push(temp);
}
}
console.log(newArr)
var arr = [50,51,52,53,54,511,512,513,514,521,522,523,524,525,526,527];
var result = [],
lastVal = -1;
while(arr.length) {
var currentIndex = arr.length - 1;
var currentValue = arr[currentIndex];
var c = Math.floor(currentValue/10);
if (c !== lastVal) {
lastVal = c;
result.push([currentValue]);
}else{
result[result.length-1].push(currentValue);
}
arr.splice(currentIndex, 1);
}
result.forEach(function(arr){ arr.reverse(); });
console.log(result);
Here's a solution using Ramda.js
const x = [50,51,52,53,54,511,512,513,514,521,522,523,524,525,526,527]
const f = R.pipe(
R.sortBy(R.identity),
R.groupWith(R.pipe(R.subtract, Math.abs, R.equals(1)))
)
console.log(f(x))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

How to separate each sub group in main group Array using javascript

I have an Array. It contains several subgroups. Example:
let mainArray=[50,51,52,53,54,511,512,513,514,521,522,523,524,525,526,527]
I want to divide that main array into sub-arrays.For example
sub1 =[50,51,52,53,54]
sub2 =[511,512,513,514]
sub3 =[521,522,523,524,525,526,527]
Can you help me?
Use the Array reduce function :
let mainArray=[50,51,52,53,54,511,512,513,514,521,522,523,524,525,526,527];
let groups = mainArray.reduce (
(grps, el, i, main) => ((el === main[i-1] + 1 ? grps[0].push (el)
: grps.unshift ([el])), grps), []);
[sub3, sub2, sub1] = groups;
console.log (sub1, sub2, sub3);
This will create an Array of Subarays:
const arr = [50,51,52,53,54, 511,512,513,514, 521,522,523,524,525,526,527];
let newArr = [];
let temp = [arr[0]];
for (let index = 1; index < arr.length; index++) {
if (arr[index] == arr[index - 1] + 1) {
temp.push(arr[index]);
} else {
newArr.push(temp);
temp = [];
}
if (index == arr.length - 1) {
newArr.push(temp);
}
}
console.log(newArr)
var arr = [50,51,52,53,54,511,512,513,514,521,522,523,524,525,526,527];
var result = [],
lastVal = -1;
while(arr.length) {
var currentIndex = arr.length - 1;
var currentValue = arr[currentIndex];
var c = Math.floor(currentValue/10);
if (c !== lastVal) {
lastVal = c;
result.push([currentValue]);
}else{
result[result.length-1].push(currentValue);
}
arr.splice(currentIndex, 1);
}
result.forEach(function(arr){ arr.reverse(); });
console.log(result);
Here's a solution using Ramda.js
const x = [50,51,52,53,54,511,512,513,514,521,522,523,524,525,526,527]
const f = R.pipe(
R.sortBy(R.identity),
R.groupWith(R.pipe(R.subtract, Math.abs, R.equals(1)))
)
console.log(f(x))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

How to find the most duplicate "values" in javascript array?

my question is actually similar to: Extracting the most duplicate value from an array in JavaScript (with jQuery)
I Found this but it always return one value only which is 200.
var arr = [100,100,200,200,200,300,300,300,400,400,400];
var counts = {}, max = 0, res;
for (var v in arr) {
counts[arr[v]] = (counts[arr[v]] || 0) + 1;
if (counts[arr[v]] > max) {
max = counts[arr[v]];
res = arr[v];
}
}
console.log(res + " occurs " + counts[res] + " times");
pls help me to return values not just one...
The result is should like this:
200,300,400
.
pls help thank you!
You have to iterate your counts to find the max occurred result.
var arr = [100,100,200,200,200,300,300,300,400,400,400];
var counts = {}, max = 0, res;
for (var v in arr) {
counts[arr[v]] = (counts[arr[v]] || 0) + 1;
if (counts[arr[v]] > max) {
max = counts[arr[v]];
res = arr[v];
}
}
var results = [];
for (var k in counts){
if (counts[k] == max){
//console.log(k + " occurs " + counts[k] + " times");
results.push(k);
}
}
console.log(results);
Create a Object iterating the arry containing the indexes of most repeated values, like below
var arr = [100,100,200,200,200,300,300,300,400,400,400];
valObj = {}, max_length = 0, rep_arr = [];
arr.forEach(function(el,i){
if(valObj.hasOwnProperty(el)){
valObj[el] += 1;
max_length = (valObj[el] > max_length) ? valObj[el] : max_length
}
else{
valObj[el] = 1;
}
});
Object.keys(valObj).forEach(function(val){
(valObj[val] >= max_length) && (rep_arr.push(val))
});
console.log(rep_arr);
After the object is created with key as array value and value as array indexes of that value, you can play/parse that. Hope this helps.
Iterating an array using for..in is not a good idea. Check this link for more information.
Hopefully below snippet will be useful
var arr = [100, 100, 200, 200, 200, 300, 300, 300, 400, 400, 400];
//Use a reduce fuction to create an object where 100,200,300
// will be keys and its value will the number of times it has
//repeated
var m = arr.reduce(function(i, v) {
if (i[v] === undefined) {
i[v] = 1
} else {
i[v] = i[v] + 1;
}
return i;
}, {});
// Now get the maximum value from that object,
//getMaxRepeated will be 3 in this case
var getMaxRepeated = Math.max(...Object.values(m));
//An array to hold elements which are repeated 'getMaxRepeated' times
var duplicateItems = [];
// now iterate that object and push the keys which are repeated
//getMaxRepeated times
for (var keys in m) {
if (m[keys] === getMaxRepeated) {
duplicateItems.push(keys)
}
}
console.log(duplicateItems)
The following would do the trick assuming that all items in arr are numbers:
//added some numbers assuming numbers are not sorted
var arr = [300,400,200,100,100,200,200,200,300,300,300,400,400,400];
var obj = arr.reduce(//reduce arr to object of: {"100":2,"200":4,"300":4,"400":4}
(o,key)=>{//key is 100,200, ... o is {"100":numberOfOccurrences,"200":numberOf...}
o[key] = (o[key])?o[key]+1:1;
return o;
},
{}
);
// obj is now: {"100":2,"200":4,"300":4,"400":4}
//create an array of [{key:100,occurs:2},{key:200,occurs:4}...
var sorted = Object.keys(obj).map(
key=>({key:parseInt(key),occurs:obj[key]})
)//sort the [{key:100,occurs:2},... by highest occurrences then lowest key
.sort(
(a,b)=>
(b.occurs-a.occurs===0)
? a.key - b.key
: b.occurs - a.occurs
);
console.log(
sorted.filter(//only the highest occurrences
item=>item.occurs===sorted[0].occurs
).map(//only the number; not the occurrences
item=>item.key
)
);
Try as following ==>
function getDuplicate( arr ){
let obj = {}, dup = [];
for(let i = 0, l = arr.length; i < l; i++){
let val = arr[i];
if( obj[val] /**[hasOwnProperty]*/ ) {
/**[is exists]*/
if(dup.find(a => a == val) ) continue;
/**[put Unique One]*/
dup.push(val);
continue;
};
/**[hold for further use]*/
obj[val] = true;
}
return dup;
};
Use ==>
getDuplicate([100,100,200,200,200,300,300,300,400,400,400]);
Try the following:
var candles = [100,100,200,200,200,300,300,300,400,400,400];
let tempArray = {}
for (let index = 0; index <= (candles.length - 1); index++) {
let valueToCompare = candles[index];
if (tempArray[valueToCompare]) {
tempArray[valueToCompare] = tempArray[valueToCompare] + 1;
} else {
tempArray[valueToCompare] = 1;
}
}
let highestValue;
Object.values(tempArray).forEach(item => {
if (highestValue === undefined) highestValue = item;
if (highestValue < item) highestValue = item;
});
console.log(highestValue);

Create Array From List of data

Hi First time Post here , please do forgive my poor English.
I have a list of data as follow
var list = '1,2,3,4,8,9,10,20,21,22,23,24'
i would like to convert this list to array, something like this
var array = ([1,4],[8,10],[20,24]);
Which it will take the first and the last(1-4) element of the list before it jump to another variable(8-10).
I have come out with some code but it's very messy
var first = true;
var firstvalue = '';
var b ='';
var endvalue ='';
var last = '';
var myArray = [];
$('.highlight').each(function() {//Loop in list
if(first){//Only For the first time to set up the loop
firstvalue = this.id;
b = firstvalue;
first = false;
return;
}
if(parseInt(this.id)-1 != b){//When gap happen and new array is insert
endvalue = b;
/*save here*/
myArray.push([firstvalue,endvalue]);
firstvalue = this.id;
b = firstvalue;
}else{
b = this.id;
}
last = this.id;//Last Item that cant capture
});
myArray.push([firstvalue,last]);
Are there any better way for this ?
Try this: easy and simple method.
var list = '1,2,3,4,8,9,10,20,21,22,23,24';
list = list.split(',');
var arrayList = [];
var firstEle = 0, lastEle = 0;
list[-1] = -2;
for(var i=-1; i<list.length; i++)
{
if(i == 0)
firstEle = list[0];
if(((list[i+1] - list[i]) > 1) && i >= 0 && i <= (list.length - 1))
{
lastEle = list[i];
arrayList.push('['+firstEle+','+lastEle+']');
firstEle = list[i+1];
}
else if(i == (list.length - 1))
{
lastEle = list[i];
arrayList.push('['+firstEle+','+lastEle+']');
}
}
alert(arrayList);
Try that:
var list = '1,2,3,4,8,9,10,20,21,22,23,24,26,27,28,30';
list = list.split(',').map(x => parseInt(x));
list.push(Infinity);
console.log(JSON.stringify(list));
var startIndex = 0;
var result = list.reduce((a, b, i, arr) => {
if(i != 0 && b - 1 != arr[i-1])
{
a.push([arr[startIndex], arr[i-1]]);
startIndex = i;
}
return a;
}, []);
console.log(JSON.stringify(result));
You could split the string and convert all values to number. Then use Array#reduce with the generated array and check the predecessor and the actual value.
If unequal with the incremented predeccessor, then concat a new array with the actual value to the result set.
Otherwise update the value at index 1 of the last array in the result set.
It works for any range sizes.
var list = '1,2,3,4,8,9,10,20,21,22,23,24',
result = list.split(',').map(Number).reduce(function (r, a, i, aa) {
if (aa[i - 1] + 1 !== a) {
return r.concat([[a]]);
}
r[r.length - 1][1] = a;
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
you can do this
var result=[];
var list = '1,2,3,4,8,9,10,20,21,22,23,24'
var dataOflist=list.split(',');
var l=dataOflist.splice(dataOflist.length-4,4);
var f=dataOflist.splice(0,4);
result[0]=f;
result[1]=dataOflist;
result[2]=l;
console.log(result);
hope this help

Comparing two arrays in Javascript

I've got two arrays in Javascript which currently look like this, but are updated by HTTP requests (node):
var x = [[292,"2349","902103","9"],[3289,"93829","092","920238"]]
var y = [[292,"2349","902103","9"],[322,"93829","092","920238"],[924,"9320","8932","4329"]]
I'm looking to compare these arrays, so that, if there is an array inside y that is not in x, it will be saved to a new array - z. Note that sometimes the order of arrays inside the arrays will change, but I would not like this to affect the result.
If there is an array inside x that is not in y, however, is should not be saved to z.
I read JavaScript array difference and have been able to replicate this, but if the x array is not shown in y, it is printed to z. I am wondering if it is possible for this not to be stored, only the different items in y?
Use a higher-order function that accepts an array (which changes with each iteration of y) and returns a new function that operates on each element (nested array) in some. It returns true if the arrays contain the same elements regardless of order.
function matches(outer) {
return function (el) {
if (outer.length !== el.length) return false;
return el.every(function (x) {
return outer.indexOf(x) > -1;
});
}
}
Iterate over y and return a list of arrays that aren't in x.
function finder(x, y) {
return y.filter(function (el) {
return !x.some(matches(el));
});
}
finder(x, y);
DEMO
You can use this function arrayDiff.
It takes two arrays (A and B) and returns an array of all elements that are in the first array and not in the second (A \ B), with any duplicates removed. Two array elements are equal if their JSON serialization is the same.
var x = [[292,"2349","902103","9"],[3289,"93829","092","920238"]];
var y = [[292,"2349","902103","9"],[322,"93829","092","920238"],[924,"9320","8932","4329"]];
var z = arrayDiff(y, x);
// z is [[322,"93829","092","920238"],[924,"9320","8932","4329"]]
// arrayDiff :: [a], [a] -> [a]
function arrayDiff(a1, a2) {
let a1Set = toStringSet(a1),
a2Set = toStringSet(a2);
return Array.from(a1Set)
.filter(jsonStr => !a2Set.has(jsonStr))
.map(JSON.parse);
// toStringSet :: [a] -> Set<String>
function toStringSet(arr) {
return new Set(arr.map(JSON.stringify));
}
}
This should work even if the order in the inner arrays is different.
I'm assuming you will have only numbers and strings in there and you don't expect a strict comparison between them.
var x = [[292,"2349","902103","9"],[3289,"93829","092","920238"]];
var y = [[292,"2349","902103","9"],[322,"93829","092","920238"],[924,"9320","8932","4329"]];
// this will do y \ x
var z = arrDiff(y, x);
console.log(z);
function arrDiff(arr1, arr2) {
var rez = [];
for (var i = 0; i < arr1.length; i++) {
if ( ! contains(arr2, arr1[i])) {
rez.push(arr1[i]);
}
}
return rez;
}
function contains(arr, x) {
x = x.slice().sort().toString();
for (var i = 0; i < arr.length; i++) {
// compare current item with the one we are searching for
if (x === arr[i].slice().sort().toString()) {
return true;
}
}
return false;
}
Try this:
function getArraysDiff(arr1, arr2) {
var x = arr1.map(function(a) { return a.join("") });
var y = arr2.map(function(a) { return a.join("") });
var z = [];
for ( var i = 0, l = arr1.length; i < l; i++ ) {
if ( y.indexOf(x[i]) == -1 ) {
z.push(arr1[i])
}
}
return z;
}
Or this:
x.filter((function(y) {
return function(x) {
return y.indexOf(x.join("")) > -1;
}
}( y.map(function(y) { return y.join("") }) )))
You can use Array.prototype.forEach(), Array.prototype.every(), Array.prototype.map(), Array.prototype.indexOf(), JSON.stringify(), JSON.parse()
var z = [];
y.forEach(function(val, key) {
var curr = JSON.stringify(val);
var match = x.every(function(v, k) {
return JSON.stringify(v) !== curr
});
if (match && z.indexOf(curr) == -1) z.push(curr)
});
z = z.map(JSON.parse);
var x = [
[292, "2349", "902103", "9"],
[3289, "93829", "092", "920238"]
];
var y = [
[292, "2349", "902103", "9"],
[322, "93829", "092", "920238"],
[924, "9320", "8932", "4329"]
];
var z = [];
y.forEach(function(val, key) {
var curr = JSON.stringify(val);
var match = x.every(function(v, k) {
return JSON.stringify(v) !== curr
});
if (match && z.indexOf(curr) == -1) z.push(curr)
});
z = z.map(JSON.parse);
console.log(z);
document.querySelector("pre").textContent = JSON.stringify(z, null, 2)
<pre></pre>
You have got 2 arrays:
var x = [[292,"2349","902103","9"],[3289,"93829","092","920238"]];
var y = [[292,"2349","902103","9"],[322,"93829","092","920238"],[924,"9320","8932","4329"]];
To create the Z array, you need the following function:
function createZ(){
var i,j,k=0,z=[],p=x;
for(j=0;j<y.length;j++){
for(i=0;i<p.length;i++){
if(y[j][0]===p[i][0] && y[j][1]===p[i][1] && y[j][2]===p[i][2] && y[j][3]===p[i][3]){
p.splice(i,1); break;
} else {
z[k++]=y[j]; console.log((y[j][0]===p[i][0])+" "+i+","+j);
}
}
}
return z;
}
Note that the createZ() also prints out the i,j of corresponding entry to the console.

Categories

Resources