Prevent double brackets when moving elements of arrays - javascript

I have two arrays (a and b) where each item has to move into another array (c)
I used the push/slice method to do this but it adds brackets into each element.
Here is the code:
let a = [0, 6, 2, 0, 1, 1];
let b = [1, 3, 9, 0, 0, 1];
let c = [];
for (let i = 5; a.length > 0 || b.length > 0; i--) {
c.push(a.splice(i, 1), b.splice(i, 1));
}
console.log(c) // I would like [element1, element2, etc]
Instead, is there another method (to replace c.push(a.splice(i, 1), b.splice(i, 1))) which does not add brackets to each element ?
Thanks!

based on the comment "it'd be nice to keep them in the same order"
using another answers use of .pop .. use .shift to remove from beginning of array instead of end
also, you can use a while loop instead
let a = [0, 6, 2, 0, 1, 1];
let b = [1, 3, 9, 0, 0, 1];
let c = [];
while(a.length > 0 || b.length) {
c.push(a.shift(), b.shift());
}
console.log(c)
Of course, the above is fine if the array lengths are the same
But, based on your original code ... this works with uneven length arrays:
let a = [0, 6, 2, 0, 1, 1];
let b = [1, 3, 9, 0, 0, 1, 99];
let c = [];
while(a.length > 0 || b.length) {
c.push(...a.splice(0,1), ...b.splice(0, 1));
}
console.log(c)
Notice the splice is always at index 0 - to maintain order

Using your exact answer all I did is access the 0 location in each spliced thing
let a = [0, 6, 2, 0, 1, 1];
let b = [1, 3, 9, 0, 0, 1];
let c = [];
for (let i = 5; a.length > 0 || b.length > 0; i--) {
c.push(a.splice(i, 1)[0], b.splice(i, 1)[0]);
}
console.log(c) // I would like [element1, element2, etc]

i already commented it, but is an answer, so here the answer
let a = [0, 6, 2, 0, 1, 1];
let b = [1, 3, 9, 0, 0, 1];
let c = [];
for (let i = 5; a.length > 0 || b.length > 0; i--) {
c.push(a.pop(), b.pop());
}
console.log(c);

Simple for loop to go through both a and b at once and add the element, if there is one:
let a = [0, 2, 4, 6, 8, 10, 12, 14];
let b = [1, 3, 5, 7, 9];
let c = [];
for (let i = 0; i < Math.max(a.length, b.length); i++) {
if (i < a.length)
c.push(a[i]);
if (i < b.length)
c.push(b[i]);
}
console.log(c);
This assumes the arrays would be of unequal length. If they are always going to be equal, then the if statements are not needed.
Alternative implementation for arrays of equal length:
let a = [0, 2, 4, 6, 8, 10];
let b = [1, 3, 5, 7, 9, 11];
let c = a.flatMap((x, i) => [x, b[i]]);
console.log(c);
If a and b have to end up empty in the end, this can be just a simple:
a.length = 0;
b.length = 0;
after c is created, instead of continually mutating the two arrays.

The spread syntax is a new addition to the set of operators in JavaScript ES6. It takes in an iterable (e.g an array) and expands it into individual elements.
The spread syntax is commonly used to make shallow copies of JS objects. Using this operator makes the code concise and enhances its readability.
So , instead use :
let a = [0, 6, 2, 0, 1, 1];
let b = [1, 3, 9, 0, 0, 1];
let c = [...a,...b]
console.log(c)

Related

How to get the position of element index of an array in an ascending order?

let a=[4, 3, 2, 2, 0, 1]
let b=[0, 1, 2, 2, 3, 4]; //My code demo below help to sort a into ascending order.
Output=[4, 5, 2, 3, 1, 0];
// Get the position of element index in a ascending order. For example, 0 is in index 4, 1 is in index 5, 2 is in index 2,2 is in index 3, and 4 is in index 0. Please Provide a demo. Thank you
var Arr = [4, 3, 2, 2, 0, 1];
for (var i = 1; i < Arr.length; i++) {
for (var j = 0; j < i; j++) {
if (Arr[i] < Arr[j]) {
var x = Arr[i];
Arr[i] = Arr[j];
Arr[j] = x;
}
}
}
console.log(Arr);
You could get the indices of the unsorted array and sort the indices by the values of the array.
const
array = [4, 3, 2, 2, 0, 1],
indices = [...array.keys()];
indices.sort((a, b) => array[a] - array[b]);
console.log(...indices);
you can use Object.entries :
let a=[4, 3, 2, 2, 0, 1]
let result = Object.entries(a).sort((a,b) => a[1]-b[1]).map(e => +e[0])
console.log(result)
i guess this is what you want
and also i change some other thing in code to be cleaner and readable
you can ask me anything if you want
function sortWithIndex (self) {
let Arr = [4, 3, 2, 2, 0, 1];
let result = [];
let ArrLength = Arr.length;
for (let i = 0; i < ArrLength; i++) {
number = Arr[i];
indexOfNumber = i;
result.push ('index ' + indexOfNumber + ' is ' + number);
};
return result
};
console.log(sortWithIndex());
Mostafa.T 🐍

Find all the same numbers in the array

I have an array with numbers in the range of 0 - 100. I need to find all the same numbers and add 1 to them.
my code worked well with arrays like [100, 2, 1, 1, 0]
const findAndChangeDuplicates = (arr: any) => {
for (let i = arr.length - 1; i >= 0; i--) {
if (arr[i + 1] === arr[i] && arr[i] <= 5) {
arr[i] += 1;
} else if (arr[i - 1] === arr[i] && arr[i] >= 5) {
arr[i] -= 1;
findAndChangeDuplicates(arr);
}
}
return arr;
};
but when I came across this
[100, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 0, 0]
my code let me down.
Expected Result:
[100, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Have any ideas?
An approach by using at least one loop from the end to adjust the values and if necessary another loop from the beginning to set the largest value to 100.
Both loops feature a value variable v. In the first loop, it starts with the last value of the array and increments its value and check is the item is smaller than this value.
If smaller, then the value is assigned, otherwise the actual value is taken for the next item.
if necessary, the other loop works in opposite direction and with a start value of 100 and checks if the item is greater than wanted and takes the smaller value, or the value is taken from the item.
The result is an array which has a gereatest value of 100 at start and goes until zero or greater to the end of the array.
function update(array) {
var i = array.length,
v = array[--i];
while (i--) if (array[i] < ++v) array[i] = v; else v = array[i];
if (array[0] > 100) {
v = 100;
for (i = 0; i < array.length; i++) {
if (array[i] > v) array[i] = v; else v = array[i];
v--;
}
}
return array;
}
console.log(update([100, 2, 1, 1, 0]));
console.log(update( [100, 100, 99, 86, 6, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 0, 0]))
.as-console-wrapper { max-height: 100% !important; top: 0; }
The following assumes you want them ordered from highest to lowest, if not this might ba as well as useless to you.
The idea is to first create an Object to keep track of how many of each number exist. We then map each value by first checking whether it's unique and if not increasing it until we can't find any value inside the Object anymore. This will not neatly order the numbers by itself so we will have to sort afterwards.
let arr1 = [100, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 0, 0],
arr2 = [100, 2, 1, 1, 0];
const f = (arr) => arr.reduce((a,c) => (a[c] = (a[c] || 0) + 1, a),{}),
g = (arr, obj) => arr.map(v => {
if (obj[v] > 1) {
let i = 1;
obj[v] = obj[v] - 1;
while (obj[v + i]) {
i++;
}
obj[v + i] = (obj[v + i] || 0) + 1;
return v + i;
} else {
return v;
}
}).sort((a,b) => +b - +a);
console.log(g(arr1, f(arr1)))
console.log(g(arr2, f(arr2)))
Here is a verbose solution that will work with unordered arrays as well.
It's not efficient, neither brilliant, but it takes care of unordered arrays as well.
Basically, it takes advantage of reduce to collect all the occurrences of each element. Each time it finds more than one, it increases all the occurrences by 1 except the last one.
Next, it checks whether there still are duplicates. If there are, it repeats the process until none is found. Of course, it's not the cleverest approach, but it works.
// Increases all duplicates until there are no more duplicates.
const increaseDuplicates = (arr, index) => {
// Repeat the code until no duplicate is found
while (!noDuplicates(arr)) {
// Acquire all the occurrences of each item, keeping track of the index.
Object.entries(arr.reduce((acc, next, i) => {
acc[next] = acc[next] || [];
return acc[next].push(i), acc;
}, {})).forEach(([n, indexes]) => {
// for each value found, check whether it appears at least twice.
if (indexes.length > 1) {
// if it does, increase the value of every item but the last one.
for (var i = 0; i < indexes.length - 1; i++) {
arr[indexes[i]]++;
}
}
});
}
return arr;
};
// Asserts an array has no duplicates.
const noDuplicates = (arr) => [...new Set(arr)].length === arr.length;
const input = [100, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 0, 0];
console.log(increaseDuplicates(input));
const unorderedInput = [6,4,5,6,6,6,6,5,6,3,1,2,3,99,403,100, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 0, 0];
console.log(increaseDuplicates(unorderedInput));
You can use a forEach on your array to do this, using the 3rd parameter of the callback, the array itself, and a bit of recursivity
const increment_to_unicity = (value, index, self) => {
if (self.indexOf(value) !== index) {
self[index]++
increment_to_unicity(self[index], index, self)
}
return self[index];
}
arr = arr.map(increment_to_unicity).sort((a, b) => b - a);

Checking which element is bigger when merging two arrays?

I have two arrays that are the same length, for example var a = [5,2,6,2,7,5]; and var b = [2,3,7,4,3];.
I also have another array which is var c = [0,0,0,0,0];
How do I compare a and b to put the highest element into c which in this case should become [5,3,7,7,5];
ES6 single-line solution:
c = a.map((a, i) => a > b[i] ? a : b[i])
Array#map into a new array, and take the max of the current number from a, and the number with the same index from array b:
const a = [5, 2, 6, 2, 7];
const b = [2, 3, 7, 4, 3];
const c = a.map((num, i) => Math.max(num, b[i]));
console.log(c);
You would iterate through both arrays, doing the comparison at each step, and inserting the larger number:
Note: Even though you mention that you have equal length arrays, the two sample arrays you've given don't have the same length so my example uses similar equal-length arrays:
let a = [5, 2, 6, 2, 7]
let b = [2, 3, 7, 4, 3]
let c = [0, 0, 0, 0, 0]
// we can use a single loop index `i` since the arrays have same length
for (let i = 0; i < a.length; i++) {
// take the current number from a and from b
let numA = a[i]
let numB = b[i]
// determine larger of the two numbers
let largerNumber = numA > numB ? numA : numB
// add larger to array at current position
c[i] = largerNumber
}
console.log(c)
You can simplify your solution to be a simple map operation, as demonstrated by dhilt.
Just use a simple for loop:
var a = [2, 3, 7, 8];
var b = [3, 2, 5, 9];
var c = [0, 0, 0, 0];
for (var i = 0; i < c.length; i++) {
c[i] = a[i] > b[i] ? a[i] : b[i];
}
console.log("Result: "+c);
try this, below code takes two arrays and gives the result of max number
var array=[5,3,7,7,5];
var array2 = [5,6,4];
var array3=array.concat(array2);
var max=array3.sort((a,b)=>b-a)[0];
console.log("Result: " + max);
see example:
var a = [5,2,6,2,7,5];
var b = [2,3,7,4,3];
var c = [0,0,0,0,0];
for(var i in c){
c[i]=a[i]>b[i]?a[i]:b[i];
}
console.log('result:' + c);

Best practice when sorting an array in pure javascript, if I have to send one group to the back

If I have the following array:
[0, 1, 3, 0, 4, 2]
And I'd like to sort it ascending order, barring zeros which I need on the end:
[1, 2, 3, 4, 0, 0]
Bear in mind I don't have access to underscore or linq.js for this solution.
My current solution works, but feels quite heavy, long, and not very elegant. Here's my code:
function sortNumbers(numbers) {
var zeroNumbers = [];
var notZeroNumbers = [];
for (var i = 0; i < numbers.length; i++) {
if (numbers[i] === 0) {
zeroNumbers.push(numbers[i]);
} else {
notZeroNumbers.push(numbers[i]);
}
}
var sortedNumbers = notZeroNumbers.sort(function (a, b) {
return parseFloat(a) - parseFloat(b);
});
for (var x = 0; x < zeroNumbers.length; x++) {
sortedNumbers.push(zeroNumbers[x]);
}
return sortedNumbers;
}
Can I improve on this solution?
This is not related to this question, but I was searching for "pure sort javascript" and this is the first answer.
Because sort mutates the original array, the best practice when sorting an array is to clone it first.
const sortedArray = [...array].sort(/* optional comparison function*/)
simply try
var output = [0, 1, 3, 0, 4, 2].sort(function(a, b) {
a = a || Number.MAX_SAFE_INTEGER; //if a == 0 then it will be a falsey value and a will be assigned Number.MAX_SAFE_INTEGER
b = b || Number.MAX_SAFE_INTEGER;
return a - b;
});
console.log(output)
var arr = [0, 1, 3, 0, 4, 2, 9, 8, 7, 0];
arr.sort(function (left, right) {
return left == right ? 0 : (left === 0 ? 1 : (left < right ? -1 : 1));
});
console.log(arr)
This will always put zeroes at the end regardless of the size of the number.
Another alternative solution using Array.sort, Array.splice and Array.push functions:
var arr = [0, 1, 3, 0, 4, 2];
arr.sort();
while(arr[0] === 0) { arr.splice(0,1); arr.push(0); }
console.log(arr); // [1, 2, 3, 4, 0, 0]
You can use sort for this, which takes a closure/callback.
var sortedArray = [0, 1, 3, 0, 4, 2].sort(function(currentValue, nextValue) {
if(currentValue === 0) {
return 1;
} else {
return currentValue - nextValue;
}
});

adding elements in array in javascript

I have an array of 5 elements ex. arr = [1,2,3,4,5]; I want to add elements between these elements, and place them in new array arr1 = [1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0];. When i alert arr1 i get the same array as it is, but when i alert arr1.length i get that it`s length is 5, when it is actually 20. Can you help me fix this, or tell me why do i get that result. Here is an example of the code i am using:
function niza(val,times){
var arr = [];
for (var i=0;i<times;i++) {
arr.push(val);
}
return arr;
}
and then this:
var y1=0;
var arr= [];
var a = new Array();
for (var j=0;j<Niza1.length;j++) {
y1 = Niza1[j];
arr = y1 + "," + niza(0,11);
a.push(arr);
}
where Niza1 holds the 5 elements mentioned before in arr, and a holds the elements mentioned in arr1.
I'm not sure to understand the code you wrote, but do you know you can add multiple elements at once with arr.push ?
var array1 = [1, 2, 3, 4, 5];
var array2 = [];
for(var i = 0 ; i < array1.length ; i++) {
array2.push(array1[i], 0, 0, 0);
}
//array2 == [1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0]
You question is a little hard to follow, but try something like this:
function inject(original, val, times) {
var res = [];
for(var i=0; i < original.length; i++){
res.push(original[i]);
for(var j = 0; j < times; j++){
res.push(val);
}
}
return res;
}
Demonstration
Here's a solution that would work with an arbitrary list and length, and is therefore reusable:
function inject(original, values) {
var result = [];
for (var i = 0 ; i < original.length ; i++) {
result.push(original[i]);
result.push.apply(result, values);
}
return result;
}
console.log(inject([1,2,3], [0,0,0]));
// output: [1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]
console.log(inject([1,1,1], [2,6,2,6]));
// output: [1, 2, 6, 2, 6, 1, 2, 6, 2, 6, 1, 2, 6, 2, 6]
It leverages the the native apply (here's an explanation) function to execute the push with an arbitrary list of arguments, defined by the values array.

Categories

Resources