Related
i am writing a simple program of array rotation.
when i console log element array , it includes empty along with other values.. why is that and whats the fix?
how can i remove empty ?
let arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let num = prompt("Enter Rotation Value : ");
const rotateFunc = (arr, d) => {
// debugger;
let result = [];
let temp = [];
let element = [];
for (let i = 0; i < arr.length; i++) {
if (i < d) {
temp[i] = +arr[i];
} else {
element[i] = +arr[i];
}
}
console.log(temp);
console.log(element);
result = element.concat(temp);
console.log(result);
};
rotateFunc(arr1, num);
results:
temp array console log result: (3) [1, 2, 3]
element array console log result: (9) [empty × 3, 4, 5, 6, 7, 8, 9]
and final result console log : (12) [empty × 3, 4, 5, 6, 7, 8, 9, 1, 2, 3]
When you assign to an element in the middle of an array, without assigning to the indexes before it, those earlier indexes still exist, they're marked "empty". Since you don't start assigning to element[i] until i is at least d, all the previous elements are empty.
Rather than assigning to specific indexes, use push() to append to the arrays starting from the beginning. Then you won't have gaps in the array.
let arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let num = prompt("Enter Rotation Value : ");
const rotateFunc = (arr, d) => {
// debugger;
let result = [];
let temp = [];
let element = [];
for (let i = 0; i < arr.length; i++) {
if (i < d) {
temp.push(arr[i]);
} else {
element.push(arr[i]);
}
}
console.log(temp);
console.log(element);
result = element.concat(temp);
console.log(result);
};
rotateFunc(arr1, num);
You also need to update your final array and remove the first d elements. You can use splice() to achieve it. It modifies the array in place
let arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let num = prompt("Enter Rotation Value : ");
const rotateFunc = (arr, d) => {
// debugger;
let result = [];
let temp = [];
let element = [];
for (let i = 0; i < arr.length; i++) {
if (i < d) {
temp[i] = +arr[i];
} else {
element[i] = +arr[i];
}
}
element.splice(0,d);
console.log(temp);
console.log(element);
result = element.concat(temp);
console.log(result);
document.write(result);
};
rotateFunc(arr1, num);
I have an array a = [1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7]
I want to fetch all the duplicate pair in this array list.
Since there are pairs of 2 and 7 the output should be -
Output: [2, 7]
I tried writing my own logic but I am very weak in that area. Can somebody help?
function getDuplicateArrayElements(arr){
let sorted_arr = arr.slice().sort();
let results = [];
for (let i = 0; i < sorted_arr.length; i++) {
let matchingElementCount = 1;
for (let j = i + 1; j < sorted_arr.length - i; j++) {
if (sorted_arr[j] === sorted_arr[i]) {
++matchingElementCount;
} else {
if(matchingElementCount % 2 === 0) {
results.push(sorted_arr[i]);
}
i = j - 1;
break;
}
}
}
return results; } var a = [1,1,1,2,2,3,3,3,4,6,6,6,7,7]; var duplicateValues= getDuplicateArrayElements(a);
You can achieve your result by using reduce and forEach.
const arr = [1,1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7];
// Generate a hashmap from the given array for counting the frequency.
const hashMap = arr.reduce((a, c) => {
a[c] = (a[c] || 0) + 1;
return a;
}, {});
const pair = [];
// If the frequency is divided by 2 then push the key of the hashMap into pair array.
Object.entries(hashMap).forEach(([k, v]) => {
if (v % 2 === 0) {
[...Array(Math.floor(v / 2))].forEach(_ => pair.push(k));
}
})
console.log(pair);
You can grab the frequency of each number, and then filter out any which have an odd frequency. You can then .flatMap() the frequencies to an array containing your number for each pair you found like so:
const a = [1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7];
const freq = a.reduce((m, n) => m.set(n, (m.get(n) || 0) + 1), new Map);
const res = [...freq].filter(([n, count]) => count % 2 == 0).flatMap(([n, c]) => Array(c/2).fill(n));
console.log(res);
This way, if you have four 1s (ie: two pairs of 1s), the filter will pick up on that, allowing you to flat-map the [1, 4] array to an array of [1, 1], which is merged into the larger resulting array.
You could create a helper map and keep the counts of each number as the values and the numbers itself as the keys. After iterating through the array, you only need to find the ones with a count divisible by 2:
var a = [1, 1, 1, 2, 2, 3, 3, 3, 4, 6, 6, 6, 7, 7]
function findDuplicates(arr) {
const map = {};
for (const curr of arr) {
if (!map[curr]) {
map[curr] = 0;
}
map[curr]++;
}
const res = [];
for (const key in map) {
if (map.hasOwnProperty(key) && map[key] % 2 === 0) {
res.push(Number.parseInt(key));
}
}
return res;
}
console.log(findDuplicates(a));
You can first count the occurrence of each numbers and if it is greater than 0 and divisible by 2 then add these to final result else don't
function getDuplicateArrayElements(arr) {
let map = {}
let results = [];
for (let num of arr) {
map[num] = map[num] || 0
map[num]++
}
return Object.keys(map)
.filter(v => map[v] && map[v] % 2 === 0)
.map(v => new Array(map[v]/2).fill(+v))
.flat()
.sort()
}
var a = [1, 1, 1, 2, 2, 3, 3, 3, 4, 6, 6, 6, 7, 7,8,8,8,8];
var duplicateValues = getDuplicateArrayElements(a);
console.log(duplicateValues)
const a = {};
[1,1,1,2,2,3,3,3,4,6,6,6,7,7].forEach(v => {a[v] = a[v] ? a[v] + 1 : 1});
const l = [];
Object.keys(a).forEach(k => !(a[k] % 2) && l.push(k));
Here you go:
function getDuplicateArrayElements(arr){
var dupilcates=arr.filter(x => arr.filter(y=>y==x).length==2);
var found=[];
for(var i=0;i<dupilcates.length;i=i+2)
found.push(dupilcates[i]);
return found;
}
This will give you the desired pairs. with [1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 6, 6, 6, 6, 7, 7] input it will return [1,1,2,6,6,7]:
function getDuplicateArrayElements(arr){
let sorted_arr = arr.slice().sort();
let results = [];
let i = 0;
while (i < sorted_arr.length) {
let counter = 1;
let j = i;
while (sorted_arr[j] === sorted_arr[j+1]) {
counter++;
j++;
}
if (counter%2 == 0) {
results.push(...Array(counter/2).fill(sorted_arr[i]))
}
i += counter;
}
return results;
}
var a = [1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 6, 6, 6, 6, 7, 7];
console.log(getDuplicateArrayElements(a));
Another rather concise solution:
a = [1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7];
uniques = new Set(a); //filter out duplicates
res = [];
uniques.forEach((key)=>{
if(a.filter(elem => elem === key).length === 2){res.push(key)};
//filter out only the elements which match the key being tested
//if there are 2, push to result
})
Edit: even more concise, but perhaps less efficient:
a = [1,1,1,2,2,3,3,3,4,4,4,6,6,6,7,7];
res = Array.from(new Set(a.filter(elem => a.filter(el => el === elem).length === 2)));
Javascript has awesome JSON object, in my opinion, you can use json as a dictionary;
{ key: _value }.
Loop throw array one times, no sort, no slice
key is array's element value, _value is frequency
var frequencies = {};
for (let i = 0; i < a.length; a++) {
if (result[a[i]] == 'over') continue;
if (result[a[i]] == undefined) { // First times
result[a[i]] = 1
} else if (result[a[i]] == 1) { // Second times
result[a[i]] = 2
} else { // Ignore if > 2
result[a[i]] = 'over'
}
}
// result: {1: "over", 2: 2, 3: "over", 4: "over", 6: "over", 7: 2}
so now pick keys have value equal 2
function getDuplicateArrayElements(numbers: number[]): number[] {
const occurences = new Map<number, number>();
for (let number of numbers) {
if (occurences.has(number)) {
const current = occurences.get(number)!;
occurences.set(number, current + 1);
} else
occurences.set(number, 1)
}
return (
Array
.from(occurences.entries())
.reduce<number[]>(
(accumulator, [key, value]) => {
if (value === 2) {
return accumulator.concat(key)
}
return accumulator
},
[]
)
)
}
const a = [1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 6, 6, 6, 7, 7];
getDuplicateArrayElements(a); // [2, 7]
My problem is I can't console.log the repeating after another same numbers in the array. I can find which number how many times appears with this code:
var array = [2, 1, 1, 2, 3, 3, 2, 2, 2, 1],
currentNum = 1,
counter = 0,
item;
for (var i = 0; i < array.length; i++) {
for (var j = i; j < array.length; j++) {
if (array[i] == array[j])
counter++;
if (currentNum < counter) {
currentNum = counter;
item = array[i];
}
}
counter = 0;
}
console.log(item + " ( " + currentNum + " times ) ");
But my real issue is that I want to log the 2, 2, 2 part and I don't know how.
Thank you guys very much in advance!
Following will find the first instance of longest (assuming more than one same length sequence)
The first reduce() creates subarrays for each sequence, the second reduce() checks lengths of those sub arrays returning the first instance of longest sequence
var array = [2, 1, 1, 2, 3, 3, 2, 2, 2, 1];
var res = array.reduce(function(a,c,i){
if(a.length && a[a.length-1][0] ===c){
a[a.length-1].push(c)
}else{
a.push([c]);
}
return a
},[]).reduce(function(a,c){
return c.length > a.length ? c : a;
});
console.log('Sequence length=',res.length);
console.log('Value=', res[0]);
If you expect multiple same length sequences and want to capture all the values that match can modify second reduce something like:
var array = [2, 1, 1, 2, 3, 3, 2, 2, 2, 1, 2, 2, 2, 7, 7, 7];
var res = array.reduce(function(a,c,i){
if(a.length && a[a.length-1][0] ===c){
a[a.length-1].push(c)
}else{
a.push([c]);
}
return a
},[]).reduce(function(a,c){
if(c.length > a.len){
// reset when longer sequence found
a.values = [c[0]];
a.len = c.length;
} else if(c.length === a.len){
// add new value when same length found
a.values.push(c[0]);
}
return a
},{len:0,values:[]});
console.log('Sequence length=', res.len)
console.log('How many times=', res.values.length)
console.log('Values = ', res.values.join() )
Array.prototype.forEach or reduce is better for iteration through an array.
Here is a solution with a single going through array (just 3 additional variables :) )
var array = [2, 1, 1, 2, 3, 3, 2, 2, 2, 1]
var item = array[0], maxTimes = 1, currentTimes = 1
array.reduce(function(prev, current) {
if (prev === current) {
currentTimes = currentTimes + 1
if (currentTimes > maxTimes) {
maxTimes = currentTimes
item = current
}
} else {
currentTimes = 1
}
return current
})
console.log(item, maxTimes)
You could use Array#reduce with an object which holds the temporary result and the actual count of the item.
If an item is equal to the last item, last count is incremented and checked if the count is greater than the temporary count. Then the temporary count is replaced by the actual count.
var array = [2, 1, 1, 2, 3, 3, 2, 2, 2, 1],
count = array.reduce(function (r, a, i, aa) {
if (a === aa[i - 1]) {
r.last.count++;
if (!(r.last.count <= r.result.count)) {
r.result = r.last;
}
} else {
r.last = { value: a, count: 1 };
}
return r;
}, { last: {}, result: {} }).result;
console.log(count);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Array length is 7
Original array
var arr = [2, 4, 6];
Needed array
arr = [null,null,2,null,4,null,6];
0 is not present in array so need to replace with null,
1 is not available replace with null and
2 is available so put 2 in new array so on..
You can use the splice() method on the array
var arr=[2,4,6];
var l = arr[arr.length-1];
for(var i=0; i<=l; i++){
if(arr[i] !== i){
arr.splice(i, 0, null);
}
}
Output : [null, null, 2, null, 4, null, 6]
This modifies the original array.
I will write a permanence case for all answers soon.
function createArrayFromArray(array, length) {
var new_array = new Array(length);
for (var i = 0; i < new_array.length; i++) {
new_array[i] = null;
}
for (var i = 0; i < array.length; i++) {
new_array[array[i]] = array[i];
}
return new_array;
}
console.log(createArrayFromArray(arr, 7)); //[null, null, 2, null, 4, null, 6]
You just need to find the max value in the array and then iterate from 0 to that max, checking each value to see if it was present in the source or not:
var arr = [2, 4, 6];
var max = Math.max.apply(Math, arr);
var result = [];
for (var i = 0; i <= max; i++) {
if (arr.indexOf(i) !== -1) {
result[i] = i;
} else {
result[i] = null;
}
}
Working demo: http://jsfiddle.net/jfriend00/c7p8mkqy/
As I asked in my comments, I'd like to know what problem you're actually trying to solve because it seems like both the original and the newly created data structures are inefficient structures that could probably use different form of data and work more efficiently. But, we can only help you make a wiser choice if you explain the actual problem, rather just your attempted solution.
Given you have the only input arr which you want to fill null inside. Try this:
var arr = [2, 4, 6];
var output = [];
while (arr.length>0){
var first = arr.splice(0,1);
while (output.length<first[0])
output.push(null);
output.push(first[0]);
}
// output should be [null,null,2,null,4,null,6];
Try:
var arr = [2, 4, 6];
var new_arr = [];
var i = 0;
while(i < 7){
var pos = arr.indexOf(i++);
new_arr.push(pos !== -1 ? arr[pos] : null)
}
document.write(JSON.stringify(new_arr, null, 4))
var arr = [2, 4, 6];
var result = new Array(7);
arr.forEach(function(a) { result[a] = a;});
Interesting quiz:
var arr = [2, 4, 6]
var n = 0
while(arr.length > n) {
if(arr[n] !== n) {
arr = arr.slice(0,n).concat(null, arr.slice(n))
}
n++
}
console.log(arr) // [null, null, 2, null, 4, null, 6]
This approach applies to array consists of random number of sorted integers.
var arr = [2, 4, 6];
var narr = (new Array(arr.sort()[arr.length-1]))
arr.map(function(v){
narr[v] = v;
});
for (var i = 0; i<narr.length; i++) narr[i]||(narr[i]=null);
console.log(narr);
Try splice():
var arr = [2, 4, 6];
var i = 0,
l = arr[arr.length - 1];
while (i < l) {
if(i !== arr[i])
arr.splice(i, 0, null);
i++;
}
console.log(arr); //[ null, null, 2, null, 4, null, 6 ]
I have an array of elements.
0,1,2,3,4,5,6,7,8,9
user can pick any number of elements and ask to move them after any 1 particular element.
example: ask for 4,5,7 to be moved after 1 for example, thus resulting in
0,1,4,5,7,2,3,6,8,9
or ask for 0,5 to be moved after 9
1,2,3,4,6,7,8,9,0,5
any pseudo code is greatly appreciated.
move_after= function(after, move_array) {
//remove elements from the array
move_array.forEach(function(element) {
var index = operations.indexOf(element);
operations.splice(index, 1);
});
var after_index = operations.indexOf(after) + 1;
//insert each move_array element to array
move_array.forEach(function(element) {
operations.splice(after_index++, 0, element);
});
}
move_after(2, [0,1]);
doesn't exactly give me what i want
Here a prototype is used, which inserts an array into an array after a specific digit:
Array.prototype.insertIntoArr = function(insert, digit) {
var i = this.indexOf(digit) + 1;
return this.slice(0, i).concat(insert).concat(this.slice(i));
}
The function moveAfter( ... ) first cleans the array from the values of toMove. Second toMove is inserted after the specific digit:
function moveAfter(arr, toMove, after) {
toMove.forEach(function (value) {
arr.splice(arr.indexOf(value), 1);
});
var res = arr.insertIntoArr(toMove, after);
return res;
}
Example
What about something like this: http://plnkr.co/edit/k2h6BWTUCFj5BS4oFF8C
(function(){
var arr = [0,1,2,3,4,5,6,7,8,9];
var userArr = [4,5,7];
var temp = [];
var pos = 1;
for(var i = arr.length; i >= 0; i--){
if(userArr.indexOf(arr[i]) !== -1){
temp.push(arr[i]);
arr.splice(i, 1);
}
}
for(var i = 0; i < temp.length; i++){
arr.splice(arr.indexOf(pos) + 1, 0, temp[i]);
}
console.log(arr);
//outputs [0, 1, 4, 5, 7, 2, 3, 6, 8, 9]
})();
Using your idea
function move_after(orig_array, after, move_array) {
//remove elements from the array
move_array.forEach(function(element) {
var index = operations.indexOf(element);
orig_array.splice(index, 1);
});
var after_index = orig_array.indexOf(after) + 1;
//insert each move_array element to array
move_array.forEach(function(element) {
orig_array.splice(after_index++, 0, element);
});
return orig_array;
}
Then you use
var result = move_after([0, 1, 2] , 2, [0,1]);
Hope it works,
Dan
Try this:
move_after = function (after, move_array) {
var i, s;
s = [];
for (i = 0; i < 10; i++)
{
// only append "i" it if is NOT in move_array
if (move_array.indexOf(i) === -1) s.push(i);
if (i == after) s.push(move_array);
}
return s;
};
Something like this?
var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var b = move_after(1, [4, 5, 7]);
var c = move_after(9, [0, 5]);
console.log(a);
console.log(b);
console.log(c);
function move_after(moveAfter, toMove) {
var arr = a.reduce(function (c, e, i) {
if (toMove.indexOf(e) === -1) {
c.push(e);
}
return c;
}, []);
var toMoveAfterIndex = arr.indexOf(moveAfter) + 1;
Array.prototype.splice.apply(
arr, [toMoveAfterIndex, 0].concat(toMove)
);
return arr;
}