Javascript function that converts array to array of "2-tuples" [duplicate] - javascript

This question already has answers here:
Split array into chunks
(73 answers)
Closed 6 years ago.
How do I write a javascript function that takes an array as its input [0, 1, 2, 3, 4, 5, 6, 7, 8] and returns [ [0, 1], [2, 3], [4, 5], [6, 7], [8] ]?

You could use Array#reduce and the index for grouping the parts.
var array = [0, 1, 2, 3, 4, 5, 6, 7, 8],
result = array.reduce(function (r, a, i) {
if (i % 2) {
r[r.length - 1].push(a);
} else {
r.push([a]);
}
return r;
}, []);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Related

An unique arrays of numbers from an Array with JavaScript

Can anyone tell me how to solv this problem please:
I tried doing this with array.map, array.filter, array.reduce but i did not got result:
Write a function putNum(arrayOfNum: number[], num: number),
which would find all possible combinations of numbers from arrayOfNum,
whose sum is equal to number. Wherein:
arrayOfNum contains only unique positive numbers (>0)
there should not be repetitions of numbers in the combination
all combinations must be unique
#param arrayOfNum: number[]
#param num: number[]
#return Array<Array<number>>
function putNum(arrayOfNum, num) {
***// write code only inside this function***
return [[1, 2], [3]];
}
// console.log(putNum([8, 2, 3, 4, 6, 7, 1], 99)); => []
// console.log(putNum([8, 2, 3, 4, 6, 7, 1], 5)); => [[2, 3], [4, 1]]
// console.log(putNum([1, 2, 3, 4, 5, 6, 7, 8], 8)); => [[1, 3, 4], [1, 2, 5], [3, 5], [2, 6], [1, 7], [8]]
let resultnum = result.filter(e => typeof e === 'number' && e > 0); // to make a new array with nums > 0
The best approach to solve this problem in optimized way is to use hash map
let twoSum = (array, sum) => {
let hashMap = {},
results = []
for (let i = 0; i < array.length; i++){
if (hashMap[array[i]]){
results.push([hashMap[array[i]], array[i]])
}else{
hashMap[sum - array[i]] = array[i];
}
}
return results;
}
console.log(twoSum([10,20,40,50,60,70,30],50));
Output:
[ [ 10, 40 ], [ 20, 30 ] ]

return a new array of rankings of the original array

For example, if your input array is [10, 5, 20], the output should be [2, 3, 1], since 10 is the second largest number, 5 is the third largest, and 20 is the largest.
This is my function:
function rankings(arr){
const result=[];
let newArr=arr.sort((a,b)=>b-a);
for (let i=0;i<arr.length;i++){
for (let j=0;j<newArr.length;j++){
arr[i]===newArr[j]? result.push(j+1): console.log('');
}
}
return(result);
}
Using my function with this array [10,5,20] as my input, my output is [1,2,3] while
rankings([10, 5, 20]); // [2, 3, 1] expected output
rankings([6, 8, 1, 12, 4, 3, 9]); // [4, 3, 7, 1, 5, 6, 2] expected output
You can also try to sort the array, and then match the indexes of the original array.
Edited to cater the case of repeated numbers
var originalArray = [10, 5, 20, 10, 20]
, setArray = [...new Set(originalArray)]
, sortedArray = [...setArray].sort((a, b) => a - b)
, dataIndex = originalArray.map(d => sortedArray.indexOf(d) + 1)
console.log(dataIndex)
You could sort the values and filter the items for avoiding same values with different ranks.
function rankings(array) {
const sorted = [...array]
.sort((a, b) => b - a)
.filter((b, i, { [i - 1]: a }) => a !== b);
return array.map(v => sorted.indexOf(v) + 1);
}
console.log(rankings([10, 5, 20])); // [2, 3, 1]
console.log(rankings([6, 8, 1, 12, 4, 3, 9])); // [4, 3, 7, 1, 5, 6, 2]
console.log(rankings([10, 5, 20, 10, 20]));

Shift entire column in multidimensional array using only javascript or ES6

I have a multidimensional array like below and I want to shift column positions using javascript or ES6 with no jquery or any other plugins.
Eg: Initial array will look like this.
1|2|3|4
2|2|6|4
4|2|3|4
9|2|7|4
How can I shift the 4th column to 1st position so that it will look like this?
4|1|2|3
4|2|2|6
4|4|2|3
4|9|2|7
Could someone can help with logic to shift any columns like this?
You could assing a mapped outer array with new items by slicing the inner arrays with a given index.
For getting the original sort, you could shiftby the delta of length and index.
const shift = (array, index) => array.map(a => [...a.slice(index), ...a.slice(0, index)]);
var array = [[1, 2, 3, 4], [2, 2, 6, 4], [4, 2, 3, 4], [9, 2, 7, 4]],
index = 3;
array = shift(array, index);
console.log(array.map(a => a.join(' ')));
array = shift(array, array[0].length - index);
console.log(array.map(a => a.join(' ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use array.map to re-arrange the values:
function rearrange(rows, pos) {
return rows.map(function(cols) {
return pos.map(function(i) {
return cols[i];
});
});
}
var old_arr;
var new_arr;
old_arr = [
[1, 2, 3, 4],
[2, 2, 6, 4],
[4, 2, 3, 4],
[9, 2, 7, 4]
];
new_arr = rearrange(old_arr, [3, 0, 1, 2]);
console.log(new_arr);
old_arr = [
[1, 2, 3, 4],
[2, 2, 6, 4],
[4, 2, 3, 4],
[9, 2, 7, 4]
];
new_arr = rearrange(old_arr, [3, 2, 1, 0]);
console.log(new_arr);

Base Algorithm Scripting by chopping the array with splice function in Javascript

Now I am working on a exercise in freecodecamp. Currently I got an logical error but do not why the failure happens.
In the code,I have to build in a function, which chop the input array based on the parameter. The testing result should be as follows:
chunkArrayInGroups(["a", "b", "c", "d"], 2) should return [["a", "b"], ["c", "d"]].
chunkArrayInGroups([0, 1, 2, 3, 4, 5], 3) should return [[0, 1, 2], [3, 4, 5]].
chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 4) should return [[0, 1, 2, 3], [4, 5, 6, 7], [8]].
chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 2) should return [[0, 1], [2, 3], [4, 5], [6, 7], [8]].
And my code are as follows:
function chunkArrayInGroups(arr, size) {
var array = [];
for (var x = 0; x < arr.length ; x+=size){
var spliceArr = arr.splice(0,size);
array.push(spliceArr);
}
array.push(arr);
return array;
}
chunkArrayInGroups(["a", "b", "c", "d","e"], 2);
For most of the conditions, the code works. But for the last condition i.e
chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 2) should return [[0, 1], [2, 3], [4, 5], [6, 7], [8]].
in this case I cannot get the correct answer. I tested in console log, and turn out the output is like
[[0, 1], [2, 3], [4, 5], [6, 7, 8]].
I know that it is not a difficult question and there are lots of better way to approach it, but can I know what is the logic fallancy in this code?
Many thanks!
Instead of splice use slice. This will also guarantees that the original array is not modified.
Like this (working demo):
function chunkArrayInGroups(arr, size) {
var array = [];
for (var x = 0; x < arr.length; x += size) {
// take elements from current index (`x`) to `x` + `size`
// (do not remove them from the original array, so the original size is not modified either)
var sliceArr = arr.slice(x, x + size);
array.push(sliceArr);
}
return array;
}
console.log(chunkArrayInGroups(["a", "b", "c", "d"], 2)); //should return [["a", "b"], ["c", "d"]].
console.log(chunkArrayInGroups([0, 1, 2, 3, 4, 5], 3)); // should return [[0, 1, 2], [3, 4, 5]].
console.log(chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 4)); // should return [[0, 1, 2, 3], [4, 5, 6, 7], [8]].
console.log(chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 2)); // should return [[0, 1], [2, 3], [4, 5], [6, 7], [8]]
It might help to add a console.log(arr) to your loop to see how the array changes over time.
You would see that it looks like this:
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[2, 3, 4, 5, 6, 7, 8]
[4, 5, 6, 7, 8]
Then, take into account your final splice and add which occurs outside of the loop:
[6, 7, 8]
Since your loop increments by size, it will exit once it has gathered all subarrays of exactly size.
Instead, I would recommend continuing until your input is empty:
function chunkArrayInGroups(arr, size) {
var array = [];
while(arr.length > 0){
var spliceArr = arr.splice(0,size);
array.push(spliceArr);
}
return array;
}
You will want to step using the size to save on the number of loops through the array. We are also saving the length so it's not fetched each time as it saves operations. Also you will notice that I'm not using var as you shouldn't be using it. Please use let for normal variables and const for variables you are not going to reassign.
function chunkArrayInGroups(arr, size) {
let array = [];
let arrayLength = arr.length;
for (let i = 0; i < arrayLength; i+=size) {
array.push(arr.slice(i, i+size));
}
return array
}
console.log(chunkArrayInGroups(["a", "b", "c", "d"], 2), [["a", "b"], ["c", "d"]])
console.log(chunkArrayInGroups([0, 1, 2, 3, 4, 5], 3), [[0, 1, 2], [3, 4, 5]])
console.log(chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 4), [[0, 1, 2, 3], [4, 5, 6, 7], [8]])
console.log(chunkArrayInGroups([0, 1, 2, 3, 4, 5, 6, 7, 8], 2), [[0, 1], [2, 3], [4, 5], [6, 7], [8]])
The issue here is that you are reducing the array length throughout your iteration. I.e. your array gets smaller within each iteration while your x continously increases. That means that before your last iteration your x will be at 6 and the array length will be 3, hence x < arr.length evaluates to false and your last iteration does not happen. The most simplistic solution that I can think of is to store the original array length into a variable I named stop and remove the unneccessary final array push outside the loop.
function chunkArrayInGroups(arr, size) {
var array = [];
var stop = arr.length;
for (var x = 0; x < stop; x+=size){
var spliceArr = arr.splice(0,size);
array.push(spliceArr);
}
return array;
}
console.log(chunkArrayInGroups([1,2,3,4,5,6,7], 2))
splice method changes the length of array on every iteration. That's why your loop exits before you expect. You can read more about splice here.
Unlike splice, slice will not remove items from the array that's why lealceldeiro answer will work as expected.
Kevin Bruccoleri answer looks cleaner and shorter but if you have an app where you store an array in to a variable and then pass it to the function, that variable will be empty after the execution of the function, which can lead to bugs in your app. That's why arrays are basically object, but that's science fiction of javascript.
function chunkArrayInGroups(arr, size) {
var array = [];
while (arr.length) {
array.push(arr.splice(0, size))
}
return array
}
var nums = [0, 1, 2, 3, 4, 5, 6, 7, 8]
console.log('now it full', nums);
console.log(chunkArrayInGroups(nums, 2));
console.log('now it empty', nums);
Used slice to copy original array two
map() and splice() to insert array from n index
const frankenSplice = (arr1, arr2, n) => {
let arr = arr2.slice();
arr1.map(e => {
arr.splice(n, 0, e);
n++;
})
return arr;
}

Symmetric Difference javascript

I am trying to solve this freecodecamp algorithm question where I had to collect the difference of two or more arrays. I used map to get the difference of array but the problem is I only get two elements;
function sym(args) {
args = [].slice.call(arguments);
var newArr = args.map(function(el, index, arr){
console.log(arr.indexOf(arr[index]));
if(arr.indexOf(arr[index] === -1 )){
// console.log(arr[index]);
return args.push(arr[index]);
}
});
return newArr; // my newArr returns [3, 4] instead of [3,4,5]
}
console.log(sym([1, 2, 3], [5, 2, 1, 4]));
//sym([1, 2, 3], [5, 2, 1, 4]) should return [3, 4, 5]
//sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1]) should return [1, 2, 4, 5, 6, 7, 8, 9]
I think we could do also this way since we want them to be ordered at the end.
For more detail about the original problem please consult this link: FreecodeCamp Link: Symmetric Difference
const sym = (...args) => {
// Merge all the different arrays and remove duplicate elements it means elements that are present both on two related arrays
let tab = args.reduce((a, b) => [
...a.filter(i => !b.includes(i)),
...b.filter(j => !a.includes(j))
], []);
// Then remove the rest of duplicated values and sort the obtained array
return Array.from(new Set(tab)).sort((a, b) => a - b);
}
console.log(sym([1, 2, 3, 3], [5, 2, 1, 4])); // [3, 4, 5]
console.log(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5])); // [1, 4, 5]
console.log(sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1])); // [1, 2, 4, 5, 6, 7, 8, 9]
The Set data structure is used here to remove duplicated values thanks to its characteristics.
Well your function is a little more complex than only selecting the unique values, cause you want to filter them out... and also accept multiple arrays. This should work.
var sym = (...arrays)=>{
//Concat Items
const allItems = arrays.reduce((a,c)=>a.concat(c), []);
// Identify repeated items
const repeatedItems = allItems.filter((v,i,a)=>a.indexOf(v) !== i);
// Filter repeated items out
const diff = allItems.filter(item=>repeatedItems.indexOf(item) < 0);
console.log(diff);
};
sym([1, 2, 3], [5, 2, 1, 4]); // [3,5,4]
I don't think your approach will work; you're supposed to create an array with elementos from both arrays, so a single .map won't do the job. Filtering through both arrays should work, although it will probably leave enough room for optimization.
my newArr returns [3, 4] instead of [3,4,5]
You are using map which will only return one value per iteration (which is why you are getting only 2 values) and in your case you are checking if the index is found or not (not the item)
You need to concatenate all the arrays and then remove those which are repeated
Concatenate
var newArr = args.reduce( ( a, c ) => a.concat( c ) , []);
Create a map by number of occurrences
var map = newArr.reduce( (a,c) => ( a[c] = (a[c] || 0) + 1, a ) , {});
Iterate and filter through those keys whose value is 1
var output = Object.keys( map ).filter( s => map[s] === 1 ).map( Number );
Demo
function sym(args)
{
args = [].slice.call(arguments);
var newArr = args.reduce( ( a, c ) => a.concat( c ) , []);
var map = newArr.reduce( (a,c) => ( a[c] = (a[c] || 0) + 1, a ) , {});
return Object.keys( map ).filter( s => map[s] === 1 ).map( Number );
}
console.log(sym([1, 2, 3], [5, 2, 1, 4]));
You could take an Object for counting the items and return only the items which have a count.
function sym(array) {
return array.reduce((a, b) => {
var count = {};
a.forEach(v => count[v] = (count[v] || 0) + 1);
b.forEach(v => count[v] = (count[v] || 0) - 1);
return Object.keys(count).map(Number).filter(k => count[k]);
});
}
console.log(sym([[3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1]]));

Categories

Resources