Create new loop for duplicate index with Javascript - javascript

Quick question. I need to create an array using duplicated index. For example, I have an array like:
var array = [2, 3, 2, 4, 3, 2, 6, 7];
And I need to get a new loop interaction for each duplicate index, the response should be something like:
[
[2, 3, 4, 6, 7],
[2, 3],
[2],
]
Please let me know if is possible and how to create some function to do it.
Thank you!

You can just use one object to store number of occurrences for each element and use that value to create result array.
var array = [2, 3, 2, 4, 3, 2, 6, 7];
var obj = {}, result = []
array.forEach(function(e) {
obj[e] == undefined ? obj[e] = 0 : obj[e] += 1;
result[obj[e]] = (result[obj[e]] || []).concat(e)
})
console.log(JSON.stringify(result))

you can do something like this
var array = [2, 3, 2, 4, 3, 2, 6, 7];
array.sort();
let idx = 0, result = [];
for(let i=0; i<array.length; i++){
if(i>0 && array[i] != array[i-1]){
idx = 0;
}
if(idx == result.length)
result[idx] = [];
result[idx].push(array[i]);
idx++;
}
console.log(result);

Related

Why JS is passing a number into the array as a string?

I'm trying to obtain // [2,6,0,8,4] from the function:
let getValidPassword = arr => {
let x = [];
for (let i in arr) {
for (let j in arr[i]) {
if (arr[i][j] % 2 !== 0) {
break;
} else {
x += arr[i][j];
}
}
}
return x
};
var loggedPasscodes = [
[1, 4, 4, 1],
[1, 2, 3, 1],
[2, 6, 0, 8],
[5, 5, 5, 5],
[4, 3, 4, 3]
];
console.log(getValidPassword(loggedPasscodes));
However when I run the typeof x, I'm getting a string(I though it was a number) and when I print x I get 26084 instead of [26084]
what witchcraft is this?
I though setting x to [ ] would make the trick...
thank you.
The problem here is that you have declared x=[] but you are modifying it as x += arr[i][j]; as soon as javascript gets to this line. It treats the array as string calling x.toString() internally and appending to that string. For example if you declare an array as a=[] and call a+=1 then a will become "1". In javascript everything is value typed, it doesn't matter what you declare when you assign some value to it or do some operation on the variable, it gets converted to the type of value.
I would recommend you to go through this
let getValidPassword = arr => {
let x = [];
let temp = [];
for (let i in arr) {
for (let j in arr[i]) {
if (arr[i][j] % 2 !== 0) {
break;
} else {
temp.push(arr[i][j]);
}
if(temp.length == arr[i].length)
x = temp.slice();
}
}
return x
};
var loggedPasscodes = [
[1, 4, 4, 1],
[1, 2, 3, 1],
[2, 6, 0, 8],
[5, 5, 5, 5],
[4, 3, 4, 3]
];
console.log(getValidPassword(loggedPasscodes));
The problem is that you are incrementing your variable, to add an element to an array you need to use the push() method.
Correct code:
let getValidPassword = arr => {
let x = [];
for (let i in arr) {
for (let j in arr[i]) {
if (arr[i][j] % 2 !== 0) {
break;
} else {
x.push(arr[i][j]);
}
}
}
return x
};
var loggedPasscodes = [
[1, 4, 4, 1],
[1, 2, 3, 1],
[2, 6, 0, 8],
[5, 5, 5, 5],
[4, 3, 4, 3]
];
console.log(getValidPassword(loggedPasscodes));
When you concatenate an array (which is what += is doing) it first converts the array and the value being appended to strings.
In order to add elements to the x array use x.push(arr[i][j]), this will insert them without type conversion.

How to log only the elements from second level array from a multidimentional array

I have the following array and I need to log only the elements from the second level array from it.
var myArr = [1, 2, 3, [10, 11,[1321,3213,[321321, true], "ha"], 133], 4, 5];
The output should be:
mySecondArr = [10, 11, 133];
with the following code, the output will include the third grade and so on arrays
for(i = 0; i < myArr.length; i++){
if (typeof(myArr[i]) == 'object'){
console.log(myArr[i])
}
}
Thank you in advance!
You can filter by Array.isArray:
const findInnerArr = outerArr => outerArr.find(item => Array.isArray(item));
const myArr = [1, 2, 3, [10, 11,[1321,3213,[321321, true], "ha"], 133], 4, 5];
const output = findInnerArr(myArr)
.filter(item => !Array.isArray(item));
console.log(output);
For more 2nd levels, you could filter by array and filter the inner arrays out and concat the result to a single array.
var array = [1, 2, 3, [10, 11, [1321, 3213, [321321, true], "ha"], 133], ['foo', 'bar', ['baz']], 4, 5],
result = array
.filter(Array.isArray)
.map(a => a.filter(b => !Array.isArray(b)))
.reduce((r, a) => r.concat(a));
console.log(result);
#CertainPerformance answer looks much better, but still for your reference, this is your way.
var newArr = [];
for(i = 0; i < myArr.length; i++){
if (typeof(myArr[i]) == 'object'){
// second level found
for(var j=0;j<myArr[i].length;j++){
if(typeof(myArr[i][j]) != 'object'){
newArr.push(myArr[i][j]);
}
}
break;
}
}
Use Array.filter, Array.reduce and Array.isArray
let myArr = [1, 2, 3, [10, 11,[1321,3213,[321321, true], "ha"], 133], 4, 5, ['this', 'should', ['not'], 'be', 'part', 'of', 'result']];
/* 1. Get all the items that are array from myArr
** 2. Reduce that array with pushing non-Array into the result. */
let result = myArr.filter((a) => Array.isArray(a)).reduce((a,c) => [...a, ...c.filter((d) => !Array.isArray(d))], []);
console.log(result);
Recursive mode get any level of the array
function getElementsAt(_array, level, currentLvl=1){
if(level< 1) throw("level must be > 1");
if(typeof _array === "undefined") throw("Array or level is undefined");
hasSubLvl = _array.some(e=>{
return e instanceof Array;
});
if(currentLvl!== level){
const __array = _array.filter(e =>{
return e instanceof Array;
})[0];
return getElementsAt(__array, level, currentLvl+1);
}
else{
return !hasSubLvl ? _array : _array.filter(e =>{
return !(e instanceof Array);
});
}
}
const arr = [1, 2, 3, [10, 11,[1321,3213,[321321, true], "ha"], 133], 4, 5];
const myArr = getElementsAt(arr, 2);
console.log(myArr, "result");
#CertainPerformance did it in the most cleanest and sweetest way.
I've used for-loops to find your result.
var myArr = [1, 2, 3, [10, 11,[1321,3213,[321321, true], "ha"], 133], 4, 5];
let ans = []
for(let i=0;i<myArr.length; i++) {
if(Array.isArray(myArr[i])) {
for(let j=0;j<myArr[i].length;j++) {
if(!Array.isArray(myArr[i][j])) {
ans.push(myArr[i][j]);
}
}
}
}
console.log(ans);
var myArr = [1, 2, 3, [10, 11,[1321,3213,[321321, true], "ha"], 133], 4, 5];
myArr = myArr.find((data) => typeof(data) ==='object');
myArr = myArr.filter((data) => typeof(data) != 'object');
console.log(myArr);
I've come with a simple solution to my own question, easy to understand for beginers :) thank you all for the help!
var myArr = [1, 2, 3, [10, 11, [1321, 3213, [321321, true], "ha"], 133], 4, 5];
for (i = 0; i < myArr.length; i++) {
if (typeof (myArr[i]) == 'object') {
var secondArr = arrayulMeu[i]
for (j = 0; j < secondArr.length; j++) {
if (typeof (secondArr[j]) != 'object') {
console.log(secondArr[j])
}
}
}
}

Remove elements from array using javascript filter

I have two arrays and want to remove duplicates using filter function.
Here is my code:
arr1 = [1, 2, 3, 1, 2, 3];
arr2 = [2, 3];
result = [1, 1];
var result = arr1.filter(function(value, index) {
for (var i = 0; i <= arr2.length; i++) {
if (value !== arr2[i]) {
return value === arr2[i];
}
}
}
Thanks in advance! Any help would be great!
You can try to convert arguments into array and then check if the value from the initial array is in arguments array:
function destroyer(arr) {
// Converting arguments into array
var args = Array.prototype.slice.call(arguments);
arr = arr.filter(function (val) {
return args.includes(val)===false;
});
return arr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3); // returns[1,1]
First of all, if its not a problem adding a library. I am using uniq from underscore.js.
uniq_.uniq(array, [isSorted], [iteratee]) Alias: unique
Produces a duplicate-free version of the array, using === to test object
equality. In particular only the first occurence of each value is
kept. If you know in advance that the array is sorted, passing true
for isSorted will run a much faster algorithm. If you want to compute
unique items based on a transformation, pass an iteratee function.
_.uniq([1, 2, 1, 4, 1, 3]);
=> [1, 2, 4, 3]
Other solution is using pure JS:
var newArray = [1, 2, 2, 3, 3, 4, 5, 6];
var unique = newArray.filter(function(itm, i, a) {
return i == newArray.indexOf(itm);
});
alert(unique);
But first you will need to combine your arrays in a new array:
var newArray = arr1.concat(arr2);
JS Fiddle
I hope this helped! :)
Here's one way without the filter function:
var arr1 = [1, 2, 3, 1, 2, 3];
var newArr = [];
for(var i = 0;i < arr1.length;i++){
if (newArr.indexOf(arr1[i]) === -1) {
newArr.push(arr1[i]);
}
}
Just use Array.prototype.filter()
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
with Array.prototype.indexOf()
The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.
var arr1 = [1, 2, 3, 1, 2, 3],
arr2 = [2, 3],
result = arr1.filter(function (a) {
return !~arr2.indexOf(a);
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
As in this JS Fiddle, using filter()
arr1 = [1, 2, 3, 1, 2, 3];
arr2 = [2, 3];
result = [1, 1];
var result = arr1.filter(myFunc);
function myFunc(value) {
for (var i = 0; i < arr2.length; ++i) {
// to remove every occurrence of the matched value
for (var j = arr1.length; j--;) {
if (arr1[j] === arr2[i]) {
// remove the element
arr1.splice(j, 1);
}
}
}
}
document.getElementById('result').innerHTML = arr1;
console.log(arr1);
// Output: [1,1]
<div id="result"></div>

How to iterate the contents of one array into the empty/undefined spots of another array?

I have an array:
var myArray = [2, 4, 6];
and another array:
var otherArray = [1, , 3, , 5, , 7];
I'm trying to map (or use any non "for/for-each" iterator) to place each myArray value into the corresponding empty spaces of otherArray.
Hopeful output:
newArray = [1, 2, 3, 4, 5, 6, 7];
Any ideas?
otherArray.forEach(function (val, idx) {
if (typeof val === 'undefined') {
otherArray[idx] = myArray.shift();
}
});
forEach may not be compatible if supporting IE < 9 though.
Using Array.prototype.map:
var newArray = otherArray.map(function(val) {
return typeof val === 'undefined' ? myArray.shift() : val;
});
Be aware that this will not hit indexes that have never been set.
Using while loop:
while (myArray.length > 0) {
var emptyIdx = otherArray.indexOf();
otherArray[emptyIdx] = myArray.shift();
}
Edit: Ok, if the elements in the array are truly not set, as they are in your description, these solutions won't work since they'll skip over the unset indexes. Here's one that would work:
var myArray = [2, 4, 6, 8, 9];
var otherArray = [1, , 3, , 5, , 7];
var lastIdx = -1;
otherArray.forEach(function(val, idx) {
if (idx - lastIdx > 1) {
otherArray[idx - 1] = myArray.shift();
}
});
if (myArray.length > 0) {
otherArray = otherArray.concat(myArray);
}
document.body.innerHTML = otherArray;
You can iterate through the array and check for undefined values like:
var otherArray = [1, , 3, , 5, , 7];
var myArray = [2, 4, 6];
for (var i = 0, j = 0; i < otherArray.length; i++) {
//check if a value is undefined
if (!otherArray[i]) {
//then change this value with the new from other array
otherArray[i] = myArray[j];
j++;
}
}
console.log(otherArray);//prints [1, 2, 3, 4, 5, 6, 7]
You could use recursivity, this function will fill the undefined items of the first array with the items of the second one until it reach the end of one of the arrays used.
var otherArray = [1, , 3, , 5, , 7];
var myArray = [2, 4, 6];
function fillArray(ar1, ar2, i){
if (!i) i = 0;
if (!ar1[i]){
ar1[i] = ar2.shift();
}
if (++i < ar1.length && ar2.length > 0){
fillArray(ar1, ar2, i);
}
}
fillArray(otherArray, myArray); // this will update the content of originals arrays,
// use otherArray.slice() to get a copy.
document.getElementById("result").innerHTML = JSON.stringify(otherArray);
<div id="result"></div>
If you want to add elements (because there is other items in myArray and there is no space left in otherArray) you can change the condition to continue replacing the && with ||
if (++i < ar1.length || ar2.length > 0){

How to remove repeated entries from an array while preserving non-consecutive duplicates?

I have an array like var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5]; I really want the output to be [5,2,9,4,5]. My logic for this was:
Go through all the element one by one.
If the element is the same as the prev element, count the element and do something like newA = arr.slice(i, count)
New array should be filled with just identical elements.
For my example input, the first 3 elements are identical so newA will be like arr.slice(0, 3) and newB will be arr.slice(3,5) and so on.
I tried to turn this into the following code:
function identical(array){
var count = 0;
for(var i = 0; i < array.length -1; i++){
if(array[i] == array[i + 1]){
count++;
// temp = array.slice(i)
}else{
count == 0;
}
}
console.log(count);
}
identical(arr);
I am having problems figuring out how to output an element that represents a group of element that are identical in an array. If the element isn't identical it should be outputted in the order that it is in in the original array.
Using array.filter() you can check if each element is the same as the one before it.
Something like this:
var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];
var b = a.filter(function(item, pos, arr){
// Always keep the 0th element as there is nothing before it
// Then check if each element is different than the one before it
return pos === 0 || item !== arr[pos-1];
});
document.getElementById('result').innerHTML = b.join(', ');
<p id="result"></p>
if you are looking purely by algorithm without using any function
var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];
function identical(array){
var newArray = [];
newArray.push(array[0]);
for(var i = 0; i < array.length -1; i++) {
if(array[i] != array[i + 1]) {
newArray.push(array[i + 1]);
}
}
console.log(newArray);
}
identical(arr);
Fiddle;
Yet another way with reduce
var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];
var result = arr.reduce(function(acc, cur) {
if (acc.prev !== cur) {
acc.result.push(cur);
acc.prev = cur;
}
return acc;
}, {
result: []
}).result;
document.getElementById('d').innerHTML = JSON.stringify(result);
<div id="d"></div>
A bit hackey, but, hell, I like it.
var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];
var arr2 = arr.join().replace(/(.),(?=\1)/g, '').split(',');
Gives you
[5,2,9,4,5]
Admittedly this will fall down if you're using sub-strings of more than one character, but as long as that's not the case, this should work fine.
Try this:
var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];
uniqueArray = a.filter(function(item, pos) {
return a.indexOf(item) == pos;
});
See Remove Duplicates from JavaScript Array

Categories

Resources