Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
javascript indexOf function is not working with mix type of array. any other alternatives
var myArray = ["2","3",5]
var found = [];
var range = 10;
for (var i = 1; i < range; i++){
if(myArray.indexOf(i) === -1)
{
found .push(i);
}
}
console.log(found)
output : [1, 2, 3, 4, 6, 7, 8, 9]
Expected output : [1,4,6, 7, 8, 9]
Why 5 is missing ?
console.log(5 === "5")
indexOf(5) isn't -1 because 5 and "5" are two different value ( indexOf uses strict equality ) MDN indexOf
console.log([5].indexOf(5))
console.log(["5"].indexOf(5))
How can i match both 5 or "5" ?
Check for both numeric and string value.
var myArray = ["2", "3", 5]
var found = [];
var range = 10;
for (var i = 1; i < range; i++) {
if (myArray.indexOf(i) === -1 && myArray.indexOf(String(i)) === -1) {
found.push(i);
}
}
console.log(found)
var myArray = ["2","3",5]
var found = [];
var range = 10;
var tmpArr = myArray.map(function(elm) {
return elm.toString();
});
for (var i = 1; i < range; i++){
if(tmpArr.indexOf(i.toString()) === -1) {
found .push(i);
}
}
console.log(found);
For this kind of use case, like to check if a value exists in a collection, you could take a Set with numbers as values and check this values agains a set of wanted numbers.
Array#indexOf takes a strict comparison and returns the index only if the value has the same identity (Identity/strict equality operator ===).
var array = ["2", "3", 5],
values = new Set(array.map(Number)),
found = [],
range = 10,
v;
for (v = 1; v < range; v++) if (!values.has(v)) found.push(v);
console.log(found);
Check for both strings and numbers as
[5] and ["5"] are treated differently because their types are different. i.e String and Number
var myArray = ["2", "3", 5]
var found = [];
var range = 10;
for (var i = 1; i < range; i++) {
if (myArray.indexOf(String(i)) === -1 && myArray.indexOf(i) === -1) {
found.push(i);
}
}
console.log(found)
Because myArray.indexOf(5) is 2 and not -1.
var myArray = ["2","3",5]
var found = [];
var range = 10;
for (var i = 1; i < range; i++){
console.log(i);
if(myArray.indexOf(i) === -1){
found .push(i);
}
}
console.log(found)
More here.
Array#indexOf only does strict equality to find the value, so because "2" === 2 and "3" === 3 are both false, then myArray.indexOf(i) returns -1 for i having the value 2 or 3.
If you want to look through an array of mixed types for only one type, then it's probably easier to make the array only one type first:
var myArray = ["2", "3", 5]
var found = [];
var range = 10;
//convery all to numbers
myArray = myArray.map(Number);
for (var i = 1; i < range; i++) {
if (myArray.indexOf(i) === -1) {
found.push(i);
}
}
console.log(found);
Alternatively, if the array has to stay with mixed types, you can use .some to check for presence and supply logic that is independent of types:
var myArray = ["2", "3", 5]
var found = [];
var range = 10;
for (var i = 1; i < range; i++) {
//lookup using loose equals
var inArray = myArray
.some(item => item == i);
if (!inArray) {
found.push(i);
}
}
console.log(found);
okay as you need you expected result as [1,4,6, 7, 8, 9]
then you have to make some changes in if condition.
why i will let you know first-run code snippet
var myArray = ["2","3",5]
var found = [];
var range = 10;
for (var i = 1; i < range; i++){
if(myArray.indexOf(i) === -1 && myArray.indexOf(String(i)) === -1)
{
found.push(i);
}
}
console.log(found)
myArray.indexOf(i) === -1 as you added
why myArray.indexOf(String(i)) === -1 because you have heterogeneous data.
int and string type data.
Related
it is a scenario where a use inputs an array of integers and it returns the most frequent integer.
it is tested 3 times but will fail once, whether its the 1st 2nd or 3rd test.
function arrayMode(array) {
if (array.length === 0) {
return null;
}
var sequence = {};
var maxNo = array[3],
maxCount = 3;
for (var i = 0; i < array.length; i++) {
var Entry = array[i];
if (sequence[Entry] === null)
sequence[Entry] = -1;
else
sequence[Entry]++;
if (sequence[Entry] > maxCount) {
maxNo = Entry;
maxCount = sequence[Entry];
} else if (sequence[Entry] == maxCount) {
maxNo += '&' + Entry;
maxCount = sequence[Entry - 1];
}
return maxNo;
}
}
console.log(arrayMode([1, 3, 3, 3, 1])) // output = 3
console.log(arrayMode([1, 2, 3, 1, 1])) // output = 1
console.log(arrayMode([2, 2, 2, 1])) // output = 2
I think there are several mistakes, if you find an entry not seen previously you set the sequence for that entry to -1, why not 1?
And you initialize maxNo to array[3] and maxCount to 3, why?
Does this make more sense to you?
function arrayMode(arr)
{
var mode = null;
var frequencies = [];
var maxFrequency = 0;
for (var i in arr)
{
var value = arr[i];
// if we haven't seen this value before, init its frequency to 0
if (frequencies[value]===undefined) frequencies[value] = 0;
// increase this value's frequency
frequencies[value]++;
// if this value's frequency is bigger than the max we've seen
// so far, this value is now the new mode.
if (frequencies[value] > maxFrequency)
{
maxFrequency = frequencies[value];
mode = value;
}
}
return mode;
}
If you want to return all modi in case there are more than one entries with the max number of frequencies (for example if for [1,1,2,3,3] you want the mode to be 1 & 3) then you can do so by a simple extra loop at the end.
This question already has answers here:
Counting the occurrences / frequency of array elements
(39 answers)
Closed 4 years ago.
Hello I want to ask how to find same number or string on array
The output must be a number or string
Example
var arr = [1,2,4,4,5,1,1,1,8,9]
Do we need to use loop , function?
You can create a frequency array. Admittedly this might not be the most efficient way.
You can use dictionaries for this. I hope you know what dictionaries are.
function fun(arr) {
var sval;
var dict = new Object();
for (var val in arr) {
sval = string(val)
if(dict[sval] === undefined) {
dict[sval] = 1;
}
else {
dict[sval]++;
}
}
var max_count = -5;
var max_count_num;
for (var key in dict) {
if (max_count < dict[key]) {
max_count = dict[key];
max_count_num = Number(key);
}
}
}
First you create an Object, which is for our purposes serves as a dictionary, then you iterate through the array. If the key is not found, hence undefined, then we create such entry, else we increment the value which is the count by 1.
We then loop through the dictionary trying to find the number with the maximum value, hence the maximum count.
I hope this is what you are looking for.
Please fix any errors in my code, I'm a bit rusty on JavaScript.
Iterate for each item on the array (i index), and iterate for each item for the rest of the array (j index, j = i+1), and create a count to any repetition of current item.
function maxRepeated(arr) {
// count global to keep the max value count
const maxRepeat = {
value: 0,
times: 0
};
for (var i = 0; i < arr.length - 1; i++) {
var maxLocal = 1; // to count ar[i] item repetitions
for (var j = i + 1; j < arr.length; j++) {
if (arr[j] == arr[i]) maxLocal++;
console.log( maxLocal )
console.log( "I " + i + " arr[i] " + arr[i] )
}
// check if maxLocal is great than max global
if (maxLocal > maxRepeat.times) {
maxRepeat.value = arr[i];
maxRepeat.times = maxLocal;
}
}
return maxRepeat;
}
const ar = [1, 2, 3, 1, 3, 5, 1, 1, 1, 5, 4, 3, 3, 2, 2, 3];
const b = ["LUNA", "LUNA", "JS", "JS", "JS"];
//console.log(maxRepeated(ar))
console.log(maxRepeated(b))
I have a comma separated string in JavaScript that I want to separate into mutiple arrays, for each column but I want to ignore the first couple of lines. So for instance I want to convert the following string,
let data = "test,data,\n,ignore,this,\n,A,B,C,\n,1,2,3,\n,1,2,3";
into arrays like the following.
["A", "1", "1"]
["B", "2", "2"]
["C", "3", "3"]
EDIT
Ths is my initial solution that I tried. Like it works but it's not really a nice solution:/
for (let i = 1; i < out.length; i++)
{
let arr = out[i].split(',');
if (i === 1)
{
for (let j = 0; j < columns; j++)
{
let col = "arr" + j;
console.log(col);
obj[col] = [arr[j]];
}
console.log(obj);
}
else
{
for (let j = 0; j < columns; j++)
{
let col = "arr" + j;
let val = arr[j];
if (j !== "")
{
obj[col].push(val);
}
}
}
}
I should point out that I eventually want to create a map of the letters to corresponding array of numbers and I won't know what the key value will be. So I'll be trying to get something like the following,
"A": ["1", "1"]
"B": ["2", "2"]
"C": ["3", "3"]
You could split by ',\n,' for getting lines and for the items split by comma. Then omit the first two arrays.
var data = "test,data,\n,ignore,this,\n,A,B,C,\n,1,2,3,\n,1,2,3",
result = data.split(',\n,').map(s => s.split(',')).slice(2);
console.log(result);
for your expected result you first have to split a string by ',' and then run for loop on a resulted array and inside that convert, you alphabet with a number and compare numbers if match found than push it into a respective array.
like below code
var datArray= [];
a = [];
b = [];
c = [];
let data = "test,data,\n,ignore,this,\n,A,B,C,\n,1,2,3,\n,1,2,3";
datArray = data.split(',');
for(var i = 0; i < datArray.length; i++) {
if(datArray[i] == 'A' || datArray[i] == 1) {
a.push(datArray[i]);
} else if(datArray[i] == 'B' || datArray[i] == 2) {
b.push(datArray[i]);
} else if(datArray[i] == 'C' || datArray[i] == 3) {
c.push(datArray[i]);
}
}
console.log(a);
console.log(b);
console.log(c);
this is one of the way you can do...
This method is not hard coded ! With this method you can handle :
ABCDEF.... , 1 2 3 4 5 6 ...
We will split for first action. Then detect Not A Number function isNaN to detect A B C .
Array helpers :
var notNumber = [];
var numbers = [];
to store data .
On the end generate your results arrays !
Try this :
var data = "test,data,\n,ignore,this,\n,A,B,C,\n,1,2,3,\n,1,2,3";
var handler = data.split(",");
var preventFlag = true;
var countNaN = 0;
var notNumber = [];
var numbers = [];
//console.log(handler);
for (var x = 0;x < handler.length;x++) {
var currentData = handler[x];
if (preventFlag == false) {
if ( isNaN(currentData) ) {
notNumber.push(currentData);
}
else {
if (currentData != "\n") {
numbers.push(currentData);
}
}
}
if (currentData == "this"){
preventFlag = false;
}
}
//console.log(notNumber)
//console.log(numbers)
for (var z = 0; z < notNumber.length;z++) {
window["result" + z] = [];
window["result" + z].push(notNumber[z]);
//console.log(window["result0"])
window["result" + z].push(numbers[z])
window["result" + z].push(numbers[z + (notNumber.length) ])
}
// GENERATE RESULT ARRAY
console.log(window["result0"]);
console.log(window["result1"]);
console.log(window["result2"]);
//["A", "1", "1"]
//["B", "2", "2"]
//["C", "3", "3"]
I have a question . How do you retrieve elements that has no double value in an array?? For example: [1,1,2,2,3,4,4,5] then you retrieve [3,5] only.
Thanks in advance
for (var j = 0; j < newArr.length; j++) {
if ((arr1.indexOf(newArr[j]) === 0) && (arr2.indexOf(newArr[j]) === 0)) {
index = newArr.indexOf(j); newArr.splice(index, 1);
}
}
If the item in the array is unique then the index found from the beginning should equal the index found from the end, in other words:
var xs = [1, 1, 2, 2, 3, 4, 4, 5];
var result = xs.filter(function(x) {
return xs.indexOf(x) === xs.lastIndexOf(x);
});
console.log(result); //=> [3, 5]
sorry for the presentation its my first post !
You have to compare each element of your array to the others in order to get the number of occurence of each element
var tab = [1,1,2,2,3,4,4,5] //The array to analyze
tab = tab.sort(); // we sort the array
show(tab); // we display the array to the console (F12 to open it)
var uniqueElementTab = []; // this array will contain all single occurence
var sameElementCounter = 0;
for(x=0;x<tab.length;x++){ // for all element in the array
sameElementCounter = 0;
for(y=0;y<tab.length;y++){ // we compare it to the others
if((tab[x]==tab[y])){
sameElementCounter+=1; // +1 each time we meet the element elsewhere
}
}
if(sameElementCounter<=1){
uniqueElementTab.push(tab[x]); //if the element is unique we add it to a new array
}
}
show(uniqueElementTab); // display result
function show(tab) { // Simple function to display the content of an array
var st="";
for(i=0;i<tab.length;i++){
st += tab[i]+" ";
}
console.log(st+"\n");
}
Hope it helps.
Here is a simple "tricky" solution using Array.sort, Array.join, Array.map, String.replace and String.split functions:
var arr = [1, 1, 2, 2, 3, 4, 4, 5];
arr.sort();
var unique = arr.join("").replace(/(\d)\1+/g, "").split("").map(Number);
console.log(unique); // [3, 5]
create new array tmp,and check already value exist by indexOf .If existed delete by splice function..
var arr = [1,1,2,2,3,4,4,5];
var tmp = [];
var dup = [];
for(var i = 0; i < arr.length; i++){
var ind = tmp.indexOf(arr[i]);
if(ind == -1){
if(dup.indexOf(arr[i]) == -1){
tmp.push(arr[i]);
}
}
else{
tmp.splice(ind,1);
dup.push(arr[i]);
}
}
console.log(tmp);
This would be my way of doing this job.
var arr = [1,1,2,2,3,4,4,5],
uniques = Object.keys(arr.reduce((p,c) => (c in p ? Object.defineProperty(p, c, {enumerable : false,
writable : true,
configurable : true})
: p[c] = c,
p), {}));
console.log(uniques);
A solution for unsorted arrays with a hash table for the items. Complexity O(2n)
var array = [1, 1, 2, 2, 3, 4, 4, 5, 1],
hash = Object.create(null),
single;
array.forEach(function (a, i) {
hash[a] = a in hash ? -1 : i;
});
single = array.filter(function (a, i) {
return hash[a] === i;
});
console.log(single);
If the array is sorted, you can solve this in O(n) (see "pushUniqueSinglePass" below):
function pushUniqueSinglePass(array, unique) {
var prev; // last element seen
var run = 0; // number of times it has been seen
for (var i = 0; i < array.length; i++) {
if (array[i] != prev) {
if (run == 1) {
unique.push(prev); // "prev" appears only once
}
prev = array[i];
run = 1;
} else {
run++;
}
}
}
function pushUniqueWithSet(array, unique) {
var set = new Set();
for (var i = 0; i < array.length; i++) {
set.add(array[i]);
}
for (let e of set) {
unique.push(set);
}
}
// Utility and test functions
function randomSortedArray(n, max) {
var array = [];
for (var i = 0; i < n; i++) {
array.push(Math.floor(max * Math.random()));
}
return array.sort();
}
function runtest(i) {
var array = randomSortedArray(i, i / 2);
var r1 = [],
r2 = [];
console.log("Size: " + i);
console.log("Single-pass: " + time(
pushUniqueSinglePass, array, r1));
console.log("With set: " + time(
pushUniqueWithSet, array, r2));
// missing - assert r1 == r2
}
[10, 100, 1000, 10000,
100000, 1000000
].forEach(runtest);
function time(fun, array, unique) {
var start = new Date().getTime();
fun(array, unique);
return new Date().getTime() - start;
}
This is much more efficient than using maps or sorting (time it!). In my machine, a 1M sorted array can have its unique elements found in 18 ms; while the version that uses a set requires 10x more.
var arr = [4, 5, 7, 8, 14, 45, 76];
function even(a) {
var ar = [];
for (var i = 0; i < a.length; i++) {
ar.push(a[2 * i + 1]);
}
return ar;
}
alert(even(arr));
http://jsbin.com/unocar/2/edit
I have tried this code in order to output even (index) elements of an array. It works, but it also outputs some empty elements. How do I fix this code to output only existing elements?
Either use modulus:
for (var i = 0; i < a.length; i++) {
if(i % 2 === 0) { // index is even
ar.push(a[i]);
}
}
or skip every second element by incrementing i accordingly:
for(var i = 0; i < a.length; i += 2) { // take every second element
ar.push(a[i]);
}
Notice: Your code actually takes the elements with odd indexes from the array. If this is what you want you have to use i % 2 === 1 or start the loop with var i = 1 respectively.
For IE9+ use Array.filter
var arr = [4,5,7,8,14,45,76];
var filtered = arr.filter(function(element, index, array) {
return (index % 2 === 0);
});
With a fallback for older IEs, all the other browsers are OK without this fallback
if (!Array.prototype.filter)
{
Array.prototype.filter = function(fun /*, thisp */)
{
"use strict";
if (this === void 0 || this === null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== "function")
throw new TypeError();
var res = [];
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in t)
{
var val = t[i]; // in case fun mutates this
if (fun.call(thisp, val, i, t))
res.push(val);
}
}
return res;
};
}
This will work on 2018 :)
take the odd indexes and apply to filter
var arr = [4, 5, 7, 8, 14, 45, 76, 5];
let filtered = arr.filter((a,i) => i%2===1);
console.log(filtered);
Even if this question is quite old, I would like to add a one-liner filter:Odd numbers: arr.filter((e,i)=>i%2)Even numbers: arr.filter((e,i)=>i%2-1)A more 'legal' way for even numbers: arr.filter((e,i)=>!(i%2))
There's no need to check with ===1 like sumit said. mod 2 already returns a 0 or a 1, you can let them be interpreted as boolean values.
You can use i&1 instead of i%2, while it benefits performance on big arrays, it can work only on 31 bit integers.
why don't you try with the % operator. It gives you the remaining of a division.
replace the loop block with
if ((i % 2) === 0) {
ar.push(a[i])
}
var arr = [4,5,7,8,14,45,76];
function even(a)
{
var ar = [];
for (x in a)
{
if((a[x]%2)==0)
ar.push(a[x]);
}
return ar;
}
alert(even(arr));
I just wanted to explain why your result is not what you expected since everyone else shows excellent solutions. You are iterating over an array size N so your resulting array will attempt to push elements in an array that will result in size N. Since only N/2 will be found in the original array your resulting array will fill the rest with blanks to fill in the rest of N. So if you checked to see if a[2*i] exists OR checked to see if a[i] % 2 == 0 before inserting, your resulting array will contain only the even indexed values
You need to test the elements for evenness like this:
var arr = [4,5,7,8,14,45,76];
function even(a){
var ar = [];
for (var i=0; i<a.length;i++){
if (a[i] % 2 === 0)
{
ar.push(a[i]);
}
}
return ar;
}
alert(even(arr));
%2 is the modulo operator, it returns the remainder of integer division.