How to print the main diagonale of array without using cycle for(...) but using array methods instead?
const arr = [
[1,6,8,-1],
[0,2,-6,5],
[0,-5,3,6],
[9,-1,1,0] ];
Here elements arr[0][0] = 1, arr[1][1]=2, arr[2][2]=3, arr[3][3]=0 are elements of the main diagonale. We can print them using cycle for:
for (let i=0;i<arr.length;i++)
{
console.log(arr[i][i]);
}
But is there a possibility to print them using methods .forEach .map or another one?
You can use Array.prototype.map but essentially they use the loops inside:
var a = [
[1,6,8,-1],
[0,2,-6,5],
[0,-5,3,6],
[9,-1,1,0] ];
var r = a.map((v, i) => v[i]);
console.log(r);
You can use array methods to get the same result, but they use for-loops inside anyways and in this case a single for-loop looks more readable to me.
However, if you really wanted to, you could do it like so:
const arr = [
[1,6,8,-1],
[0,2,-6,5],
[0,-5,3,6],
[9,-1,1,0] ];
const result = arr.map((sub_array, index) => sub_array.filter((number, index2) => index === index2));
console.log(result);
Related
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);
I want to merge two arrays both array contains another array inside. refer below two arrays.
const arr1=
[{"projectId":30278,"projectName":null,"details":[{"amount":"9097457.11","currency":"USD","paymentDate":"2016-05-16T00:00:00"}]},{"projectId":37602,"projectName":null,"details":[{"amount":"8234743.0","currency":"USD","paymentDate":"2019-04-30T00:00:00"},{"amount":"8234743.0","currency":"USD","paymentDate":"2019-04-23T00:00:00"}]}]
const arr2=
[{"projectId":30278,"projectName":null,"details":[{"amount":"8097457.11","currency":"USD","paymentDate":"2016-05-16T00:00:00"}]},{"projectId":37602,"projectName":null,"details":[{"amount":"7234743.0","currency":"USD","paymentDate":"2019-04-30T00:00:00"},{"amount":"7234743.0","currency":"USD","paymentDate":"2019-04-23T00:00:00"}]}]
when i used ES6 spread operator, both values are appended to single array. But I want to merge based upon prjectId in that array.
So after merge, i need to get the result like below
const result =
[{"projectId":30278,"projectName":null,"details":[{"amount":"9097457.11","currency":"USD","paymentDate":"2016-05-16T00:00:00"},
{"amount":"8097457.11","currency":"USD","paymentDate":"2016-05-16T00:00:00"}
]},
{"projectId":37602,"projectName":null,"details":[{"amount":"8234743.0","currency":"USD","paymentDate":"2019-04-30T00:00:00"},{"amount":"8234743.0","currency":"USD","paymentDate":"2019-04-23T00:00:00"},
{"amount":"7234743.0","currency":"USD","paymentDate":"2019-04-30T00:00:00"},{"amount":"7234743.0","currency":"USD","paymentDate":"2019-04-23T00:00:00"}
]}]
const arr1=
[{"projectId":30278,"projectName":null,"details":[{"amount":"9097457.11","currency":"USD","paymentDate":"2016-05-16T00:00:00"}]},{"projectId":37602,"projectName":null,"details":[{"amount":"8234743.0","currency":"USD","paymentDate":"2019-04-30T00:00:00"},{"amount":"8234743.0","currency":"USD","paymentDate":"2019-04-23T00:00:00"}]}]
const arr2=
[{"projectId":30278,"projectName":null,"details":[{"amount":"8097457.11","currency":"USD","paymentDate":"2016-05-16T00:00:00"}]},{"projectId":37602,"projectName":null,"details":[{"amount":"7234743.0","currency":"USD","paymentDate":"2019-04-30T00:00:00"},{"amount":"7234743.0","currency":"USD","paymentDate":"2019-04-23T00:00:00"}]}]
var fullArray = [...arr1,...arr2];
var mergedData ={};
fullArray.forEach(function(data){
if(mergedData[data.projectId]){
mergedData[data.projectId]["details"] = mergedData[data.projectId]["details"].concat(data.details)
} else {
mergedData[data.projectId] = data;
}
})
console.log(Object.values(mergedData))
You can easily achieve that using Lodash unionBy function.
const result = _.unionBy(arr1, arr2, 'projectId')
You can also try this in this case scenario.
let mergedArr = [];
let projectIdsArr1 = arr1.map(item => item.projectId);
arr2.map(outerLoopItem => {
if (projectIdsArr1.includes(outerLoopItem.projectId)) {
let found = arr1.find(innerLoopItem => innerLoopItem.projectId === outerLoopItem.projectId);
found.details = [...found.details, ...outerLoopItem.details];
mergedArr.push(found);
} else mergedArr.push(outerLoopItem);
});
console.log(mergedArr);
I receive a data value from a API, and I want to make a condition to deal with it. Sometimes it can comes as an array or object. I will use a simple example.
data = [1,2,3] // These values come from API
data.map(i => i++)
The problem is: Sometimes data can also comes as this
data = {
arr: [1,2,3]
}
// It evals an error in .map, because now "data" is an object
I know that I can solve it making something like this:
if(Array.isArray(data))
data.map(i => i++);
else
data.arr.map(i => i++);
But my code is not just a one line .map. Is there a way to make this simple condition without copying and paste code?
Thanks!
You can for example assign the array reference to another variable and use it in the rest of your code, like this:
let arr = Array.isArray(data) ? data : data.arr;
arr.map(i => i++)
A simple OR (||) operator is pretty idiomatic JavaScript:
(data.arr || data).map(i => ++i);
If the data.arr property is defined, that will be mapped, otherwise data itself will be mapped.
Complete snippet:
Note: the post-increment operator would have no effect, so I replaced it with a pre-increment.
let data, result;
data = [1, 2, 3];
result = (data.arr || data).map(i => ++i);
console.log(result);
data = {
arr: [1, 2, 3]
}
result = (data.arr || data).map(i => ++i);
console.log(result);
You can use the ternary operator.
Array.isArray(data)
? data.map(i => i++);
: data.arr.map(i => i++);
You can use destruction es6 , not sure its a good idea but you can achieve your functionality in single line. ;)
let { arr=data } = data;
arr.map(i => i++)
if arr key is not found in data then it will assign default data array.
Cheers
You can do it like this
You can use the ternary operator and assign the value as array directly to temp if it is an Array and if not than you assign using the property like input.arr which is an Array.
So once the value is in form of array than you can use the single map statement so you need not to repeat your map statement.
let data = [1,2,3];
let data1 = {
arr: [1,2,3]
}
function handle(input){
let temp = Array.isArray(input) ? input : input.arr
return temp.map(i => i++);
}
console.log(handle(data))
console.log(handle(data1))
If you don't wish to use an if or a ternary operator you can use Object.values(data).flat() to convert your data into:
[1, 2, 3]
This will essentially not modify your array and leave it be, however, it will compress your data object into an array form.
See working examples below:
Data form 1 (obj):
const data = {arr: [1, 2, 3]};
const res = Object.values(data).flat().map(i => ++i);
console.log(res);
Data form 2 (array):
const data = [1, 2, 3];
const res = Object.values(data).flat().map(i => ++i);
console.log(res);
Do note, however, Object.values does not guarantee order, and thus your array may lose its order. Moreover, if you plan to use this in production .flat() isn't yet supported across all browsers and instead, you may consider looking at a polyfill option
Long story short, i'm looking for a way to create and fill 2D arrays using ES6, in an effort to avoid for loops. The created array should contain all 0s. I've tried many different approaches so i cant post all of them.
var [r, c] = [5, 5];
var m = Array(r).fill(Array(c).fill(0));
This works but it creates a bunch of instances of the same array, and adding slice Array(r).fill(Array(c).fill(0).slice()); doesn't help either.
I also tried creating the empty arrays and then looping trough them but that's a whole different problem, you apparently can't forEach() or map() an empty array, and i couldn't even loop through a filled one efficiently.
Am i missing something here? Are a whole lot of for loops the best way to approach this? It looks really messy and overly long. Any help appreciated.
Doing this worked for me:
var [r, c] = [5, 5];
var m = Array(r).fill().map(()=>Array(c).fill(0));
Basically just filling it with a dummy value so you can map over it
You could use Array.from that takes a callback function and inside return arrays with 0's using fill method.
const arr = Array.from(Array(2), () => Array(5).fill(0))
console.log(arr)
Or you could just create array where each element is number of elements in sub-array and then use map and fill methods.
const arr = [5, 5].map(e => Array(e).fill(0))
console.log(arr)
For those needing the same thing but with undefined as each value this also works.
const x = 100;
const y = 100;
const grid = [...new Array(x)].map(() => [...new Array(y)]);
To fill the array simply map the inner value.
This will make an array filled with 0 for each value.
const x = 100;
const y = 100;
const grid = [...new Array(10)].map(() => [...new Array(10)].map(() => 0));
const nthArray = (n) => Array.from(Array(n), () => Array(5).fill(0))
const arr = nthArray(3);
console.log(arr);
I got an Array a = [1,2,3,4,5] and an Array b = [1,3] which contains some elements of a. So it is a kind of a sub array of a.
In this for loop below, I can use the elements of b to "do smething". Now, how can I interact in the same loop with the elements of a that are not a part b? That means 2, 4 and 5 from a? How to filter them out?
function action (){
for (var i=0; i<b.length; i++) {
b[i].x = "do something";
}
Thanks so much"
You can use the filter() function combined with the includes() function to filter the list:
const diff = a.filter(i => !b.includes(i));
diff will contain just the elements in a that aren't in b.
This is called a difference between the arrays. There are also a lot of libraries that will include a some sort of diff function for arrays.
You can use filter on your a array to get a new list of elements not contained:
a.filter(item => !b.includes(item)).forEach(function(item) {
console.log(item);
});
You are looking for this : a.filter((element) => !b.includes(element))
Sample
const a = [1,2,3,4,5];
const b = [1,3]
const elements_in_a_not_in_b = a.filter((element) => !b.includes(element))
console.log(
elements_in_a_not_in_b
)