Removing a specific element from each array in a 2D array - javascript

I am trying to remove the 3rd element from each array with the array.
What I have:
data =
[["51.9435","-4.26697","450","125"],
["51.9437","-4.26717","450","125"],
["51.9438","-4.26733","450","125"],
["51.944","-4.26748","450","125"]]
What I need:
data =
[["51.9435","-4.26697","125"],
["51.9437","-4.26717","125"],
["51.9438","-4.26733","125"],
["51.944","-4.26748","125"]]
I have assumed using splice but can not think how I would use it with a 2d array.

Use splice on each subarray.
const data = [["51.9435","-4.26697","450","125"],
["51.9437","-4.26717","450","125"],
["51.9438","-4.26733","450","125"],
["51.944","-4.26748","450","125"]]
for( const array of data )
array.splice(2, 1)
console.log(data)
Edit: to keep the original data intact, you'd need to copy the arrays prior to splicing.
const data = [["51.9435","-4.26697","450","125"],
["51.9437","-4.26717","450","125"],
["51.9438","-4.26733","450","125"],
["51.944","-4.26748","450","125"]]
const converted = data.map(function(array){
const copy = array.slice()
copy.splice(2, 1)
return copy
})
console.log(data)
console.log(converted)

You can use the following code snippet
data =[["51.9435","-4.26697","450","125"],
["51.9437","-4.26717","450","125"],
["51.9438","-4.26733","450","125"],
["51.944","-4.26748","450","125"]];
data.map( (arr) => {arr.splice(2,1);});
console.log(data);

You can use .map() with .splice().
.map() creates a new array with values returning from callback function.
.splice() removes one or more elements from the array.
Demo:
let data =[
["51.9435","-4.26697","450","125"],
["51.9437","-4.26717","450","125"],
["51.9438","-4.26733","450","125"],
["51.944","-4.26748","450","125"]
];
let removeIndex = (array, index) => array.map(a => (a.splice(index, 1), a));
console.log(removeIndex(data, 2));
Docs:
Array.prototype.map()
Array.prototype.splice()
Arrow Functions

you can use splice supplying the index of the index you want to remove in this case 2 and 1 if you want to remove only one element.
data = [
["51.9435", "-4.26697", "450", "125"],
["51.9437", "-4.26717", "450", "125"],
["51.9438", "-4.26733", "450", "125"],
["51.944", "-4.26748", "450", "125"],
]
data.forEach( arr => {
// loop over all arrays to get the individual ones.
arr.splice(2 , 1) // then call splice.
})
console.log(data)

Related

Why forEach doesn't working for type changing of item of array

I'm trying to change the type of each element of the array to numeric, but the string iterating over the array and transforming seems to be ignored and the original array remains the same.
arr.forEach(item => Number(item));
This is because you are not assigning it to the source array or not replacing the array with the new one that has all elements of the number type
You can also make it short as
arr.map(Number)
1) Assigining the converted number(from string to number type) back to source array index
const arr = ["1", "2", "5", "7"];
arr.forEach((n, i, src) => (src[i] = Number(n)));
console.log(arr);
2) Assigning a new array that has all elements converted to type number back to arr variable.
let arr = ["1", "2", "5", "7"];
arr = arr.map(n => Number(n));
console.log(arr);
// Foreach does not return anything, so any update you want to save has to be done manually
arr = ['1','200'];
arr.forEach(item => Number(item));
console.log(arr);
// here you are updating the orinal array
arr = ['1','200'];
arr.forEach((item, i ) => arr[i] = Number(item));
console.log(arr);
// here you are creating a new array without impacting the existing array
arr = ['1','200'];
let newArr = arr.map((item) => Number(item));
console.log(arr);
console.log(newArr);
forEach doesn't return anything. It just mutates the array that it's given.
Its callback accepts three arguments. The first is the array element, the second is the index of that element, and the last is the array itself. We only have concern ourselves with the first two in this example.
Because forEach mutates the array you need to assign the the result of coercing the string to a number back to the array index.
const arr = ['1', '2', '3'];
arr.forEach((item, i) => {
arr[i] = Number(item);
});
console.log(arr);
The alternative is to use map which creates a new array. We can use Number directly as the callback because it only accepts one argument which will be the array element.
const arr = ['1', '2', '3'];
const newArr = arr.map(Number);
console.log(newArr);

Return only value of listed index from an array JavaScript

I'm trying to filter an array based on the listed index in another array.
For example:
const item = ['apple','orange','watermelon','pineapple'];
const index = [1,3];
Based on the index array , I want to return an array of [ 'orange','pineapple']
How do I do that in an efficient way? I tried using comparison between 2 array , but i think it is not very good for efficiency.
You can do map over the index array and just do a regular indexing to look up the item from the item array.
const result = index.map(idx => item[idx]);
No need for comparisons when you already have the indices. You just access them directly instead.
You can do something like this:
const filteredArray = index.map(i => item[i]);
Output:
You can do the following,
const res = [];
item.forEach((item, idx) => { if(index.includes(idx)) res.push(item); });
console.log(res);

Sorting multidimensional array based on multiple criteria

I'm trying to figure out an efficient method to sort a multidimensional array based on how many values of another array exist.
Given the following array:
[1,2,3,4,5,6,7,8,9,10]
I am trying to sort another array of arrays based on how many of those values are included.
[
[1,3,5,7,9,22],
[1,200,300,400,500,600],
[1,2,3,4,5,6]
]
So the code I'm trying to get to would return:
[
[1,2,3,4,5,6],
[1,3,5,7,9,22],
[1,200,300,400,500,600]
]
I think what I'm doing is very inefficient and could be written better or more succinctly with a method I'm not aware of?
https://jsfiddle.net/gb3fsLdv/
const compareNums = [1,2,3,4,5,6,7,8,9,10];
let ourData = [
[1,2,3,100,200,300],
[100,200,300,400,500,600],
[1,2,3,5,6,9]
];
function sortArr(compare, data){
let indexMatches = [];
data.map(arr => {
let count = 0;
compare.map(num => {
if(arr.includes(num)){
count++
}
})
indexMatches.push(count);
})
// So now I have indexMatches with a count of how many hits each array has in the correct index order as the original data
// And I can use data to sort them based on these values...
// Little stuck how to relate the two so the same sorting happens to both arrays
}
sortArr(compareNums, ourData);
First convert the given array to set. And then use filter() to get the count of elements included in other array
const data = [
[1,3,5,7,9,22],
[1,200,300,400,500,600],
[1,2,3,4,5,6]
]
let arr = [1,2,3,4,5,6,7,8,9,10];
function getCount(arr, set){
return arr.filter(x => set.has(x)).length
}
function sortOnCount(data, arr){
let set = new Set(arr);
return data.slice(0).sort((a, b) => getCount(b, set) - getCount(a, set))
}
console.log(sortOnCount(data, arr))

Fetch unique elements from Array of Array

I have a Array of String array i want to fetch the unique elements from that array ignoring the case. how can i fetch
Example:
List of array:
[
["java,C,Node,ReactJs"]
["c","Spring"]
["undefined"]
["asdja"]
["Java","Spring"]
["adjasjh"]
["adjasjh"]
["java"]
]
ExpectedList:
[java,C,node,reactjs,spring,..]
Join the array, change to lower case, split by comma, convert into a Set to get the unique words, and then spread back to an array:
const arr = [["java,NO,C,Node,ReactJs"],["c","Spring"],["undefined"],["asdja"],["Java","Spring"],["adjasjh", "Spring-roll"],["adjasjh"],["java", "javascript", "java-script"]];
const result = [...new Set(arr.join().toLowerCase().split(','))];
console.log(result);
Older answer - won't work in all cases:
You can join the array of arrays, and use String.match() with negative lookahead RegExp to get unique strings:
const arr = [["java,NO,C,Node,ReactJs"],["c","Spring"],["undefined"],["asdja"],["Java","Spring"],["adjasjh", "Spring-roll"],["adjasjh"],["java", "javascript", "java-script"]];
const result = arr.join()
.match(/([^,]+\b)(?!.+\1[,|$])/ig);
console.log(result);
You can use reduce and map methods to iterate array and words and also Set to return array of unique elements in the end.
const array = [["java,C,Node,ReactJs"], ["c","Spring"], ["undefined"], ["asdja"], ["Java","Spring"], ["adjasjh"], ["adjasjh"], ["java"] ]
const result = [...new Set(array.reduce((r, e) => {
return r.concat(...e.map(s => s.split(',').map(w => w.toLowerCase())))
}, []))]
console.log(result)
You can flatten your array, convert every value to lowercase, use Set to remove duplicates, and Array.from to convert it back to an array.
If your ["java,C,Node,ReactJs"] is actually: ["java","C","Node","ReactJs"] you can do it this way:
const array = [
["java","C","Node","ReactJs"],
["c","Spring"],
["undefined"],
["asdja"],
["Java","Spring"],
["adjasjh"],
["adjasjh"],
["java"]
];
const unique = Array.from(
new Set([].concat.apply([], array).map(item => item.toLowerCase()))
// ^^^ flatten array
);
console.log(unique);
You could flat the data and use a Map for keeping the first unique value without mutating it.
const flat = (r, a) => Array.isArray(a) ? a.reduce(flat, r) : r.concat(a.split(','));
var data = [["java,C,Node,ReactJs"], ["c", "Spring"], ["undefined"], ["asdja"], ["Java", "Spring"], ["adjasjh"], ["adjasjh"], ["java"]],
unique = Array.from(data
.reduce(flat, [])
.reduce((m, v) => ((l => m.has(l) || m.set(l, v))(v.toLowerCase()), m), new Map)
.values()
);
console.log(unique);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Javascript - Get Array of indices for 'WILL BE' relationship after sort

I have a very simple question. Say I have an array
a = [10,40,30,20,60,50]
After sorting, it would be (assuming I use sort_a = a.sort())
sort_a = [60,50,40,30,20,10]
I want to create an array of indices from a which specify which location in the sorted array that element WILL BE after sorting. From the above example, the result would be
a_sortedindices = [6, 3, 4, 5, 1, 2]
..meaning 10 is in the 6th position when sorted, 40 is in the 3rd position... etc
Pair the values with their current indices
Sort the array of pairs based on the original values
Combine the pairs with their new indices
Sort the new array based on the original indices
Obtain the new indices from the sorted array
let values = [10,40,30,20,60,50];
let indices = values
.map((v, i) => ({ v, i }))
.sort((l, r) => r.v - l.v)
.map(({v, i}, i2) => ({ v, i, i2 }))
.sort((l, r) => l.i - r.i)
.map(p => p.i2);
console.log(indices);
This results in an array of 0-based indices because JavaScript uses 0-based indices. If you want 1-based indices like in your question, you can change p.i2 to p.i2 + 1 in the second to last line.
One of the ways, apart from many to achieve this:
1) Transform the array into another with old indices
2) Sort the array in descending order
3) Create an answer array since you now know the old and new indices.
let a = [10,40,30,20,60,50];
let transformed = a.map((v,i)=> {
return {num:v,old:i};
});
transformed.sort((a,b)=> {
return b.num - a.num;
});
let ans = [];
transformed.forEach((v,i) => {
ans[v.old] = i+1;
});
console.log(ans);
Not sure if this is a trick question or if you're trying to find the most minimal method for achieving this, but you basically already have it. This is what I came up with:
var a = [10,40,30,20,60,50];
var sort_a = a.slice(0).sort((a1,a2) => a2 - a1);
var a_sortedindices = a.map( a1 => sort_a.indexOf(a1) + 1 );
console.log(a_sortedindices);
Walking through it, I'll explain each part.
First, off you have to sort it. Looks like you need reverse sorting, so we'll add an arrow function describing a reverse sort, but before we do that, we'll also clone the array, otherwise we'll lose the original indexes of the values. .slice(0) is a nice way to return a clone of an array
var sort_a = a.slice(0).sort((a1,a2) => a2 - a1);
Then we'll map each value of the origin array. .map() is nice and easy to quickly manipulate each element in an array. We use .indexOf() to figure out where it was at in the original array. We add one to that value because you're not using zero-based indexing.
var a_sortedindices = a.map( a1 => sort_a.indexOf(a1) + 1 );
And voila. You have the sorted indexes.
A naive way of doing this job could be;
var arr = [10,40,30,20,60,50],
idx = arr.map(function(n){return this.indexOf(n)+1;}, arr.slice().sort((a,b) => b-a));
console.log(idx);
where the this argument for the .map() function callback is arr.slice().sort((a,b) => b-a)
// the array to be sorted
var list = [10,20,30,40];
// temporary array holds objects with position and sort-value
var mapped = list.map(function(el, i) {
return { index: i, value: el };
})
// sorting the mapped array
mapped.sort(function(a, b) {
return b.value - a.value;
});
// you can then remap the sorted mapped array to hold just the indices
P.S.: For future reference MDN is your friend

Categories

Resources