Is there any operation in Javascript just like [x for x in array] in python?
For example, I'm using javascript to reading a json file where there're dozens of (key, value) pairs needed to be handled(or transformed into other format). And I thought working in this way is stupid:
let transformed = []
for (let key in json){
transformed = [ /* doing some transform*/ ]
}
Is there anything like:
let transformed = [
lambda function1(key), lambda function2(value) for key, value in json
]
Thanks in advance.
The rough equivalent of Python's list comprehension is Array.map:
const myArray = [1, 2, 3]
const transformed = myArray.map((item) => item + 1)
// [2, 3, 4]
But your example is not about an array, but about an Object with keys and values. In Python, this would be a dict, and you'd use a dict comprehension along the lines of {function1(key): function2(value) for key, value in my_dict.items()}.
In JavaScript, you can turn such an object into an array with Object.entries, then perform the map, and finally transform it back into an object using Object.fromEntries:
const myObject = { a: 1, b: 2 }
const transformed = Object.fromEntries(Object.entries(myObject)
.map(([key, value]) => [key + 'x', value + 1]))
// { ax: 2, bx: 3 }
Note that fromEntries is fairly new and you might need to add a polyfill for it.
You can use a code likes this. You must use a function that handle operation on current single item.
const words = ['hello', 'bird', 'table', 'football', 'pipe', 'code'];
const capWords = words.forEach(capitalize);
function capitalize(word, index, arr) {
arr[index] = word[0].toUpperCase() + word.substring(1);
}
console.log(words);
// Expected output:
// ["Hello", "Bird", "Table", "Football", "Pipe", "Code"]
First of all, javascript does NOT support Associative Arrays. If you are used to them in Python, PHP, and other languages you need to do a little workaround in JS to achieve the same functionality.
The most common way to simulate an associative array is using an object.
let testObject = {name: "Color", value: "Red"};
And then you push every object into an array so you end up with something like this:
let testArray = [{name: "Color", value: "Red"}, {name: "Color", value: "Blue"}];
Once you have this array consisting of objects, you can use map function to go through every object in the array and do whatever you want with it.
testArray.map((item, index) => {
console.log("The value of "+index+". item is: "item.value);
})
You can use Array.map() function. It work pretty like Array.forEach() function
const numbers = [1, 2, 3, 4, 5]
let newArray = numbers.map((element) => {
return element * 2
})
console.log(newArray) // excepted : [ 2, 4, 6, 8, 10 ]
It can be reduce using
const numbers = [1, 2, 3, 4, 5]
let newArray = numbers.map(element => element * 2)
console.log(newArray) // excepted : [ 2, 4, 6, 8, 10 ]
For more informations, you can this documentation https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Related
I have this object
{
Bamboo: 7,
Eucalipto: 1,
Frassino: 2,
Ulivo: 1
}
I want to trasform this object in an array of object
[
{
plantName: Bamboo,
quantity: 7
},
{
plantName: Eucalipto,
quantity: 1
},
{
plantName: Frassino,
quantity: 2
},
{
plantName: Ulivo,
quantity: 1
},
]
What have you tried so far? Here's what I might do.
const dataObject = { Bamboo: 7, Eucalipto: 1, Frassino: 2, Ulivo: 1 };
const dataArray = Object.keys( dataObject ).map( ( key ) => {
return { 'plantName': key, 'quantity': dataObject[key] };
} );
console.log( dataArray );
You can map over the entries of the object, creating a new object with each key-value pair.
let obj = { Bamboo: 7, Eucalipto: 1, Frassino: 2, Ulivo: 1 };
let res = Object.entries(obj).map(([plantName,quantity])=>({plantName, quantity}));
console.log(res);
As you can see there are many different ways of doing this. But here are the basic steps as I learned them when I was starting out.
Create an array.
Iterate over the object.
Create a new object, and assign the key of the input object to "plantName", and the value of the input object to "quantity".
Add that new object to an array.
Here's an old-school way of achieving this:
const obj = { Bamboo: 7, Eucalipto: 1, Frassino: 2, Ulivo: 1 };
// Create an array
const arr = [];
// Iterate over the object
for (const key in obj) {
// Create a new object assigning the key
// to `plantName`, and the value to `quantity`
const newObj = {
plantName: key,
quantity: obj[key]
};
// Add the new object to the array
arr.push(newObj);
}
// Et voila!
console.log(arr);
Once you understand the basic concepts then you can start to introduce more complex methods like Object.entries, and map, but if you're just starting out with JavaScript this is probably more than enough to help you understand the process.
I have two arrays of objects (10 objects in each arrray) ->
arr1 = [{name: '', age: ''}...]
and
arr2 = [{surname: '', position: ''}...]
which I hold in two separated states.
My goal is to create the third array of the objects which contains also 10 elements
arr3=[{name: arr1.name, surname: arr2.surname}...]
How can I do this ?
As long as it is a 1 to 1 where each index matches, it is a simple Array map and using the spread to copy over the properties and values.
const arr1 = [{a: 1, b: 2}, {a: 3, b: 4}];
const arr2 = [{c: 11, d: 22}, {c: 33, d: 44}];
const arr3 = arr1.map((obj, ind) => ({...obj, ...arr2[ind]}), []);
console.log(arr3);
This is what you need,
let arr3 = []
arr1.forEach((obj1, index) => {
let obj3 = {...obj1, ...arr2[index]}
arr3.push(obj3)
})
If the indexes are assumed to match between the two arrays (which also implies that the two arrays are the same length), you can use map() on one array and use its index parameter to reference the other array. (It doesn't really matter which.)
For example:
const arr3 = arr1.map((a, i) => ({
name: a.name,
surname: arr2[i].surname
}));
Note that this is based on the example shown, where only two properties (one from each array) are in the resulting objects. If you want all properties in the resulting objects, you don't need to specify all of them. You can just combine them all:
const arr3 = arr1.map((a, i) => ({
...a,
...arr2[i]
}));
Here is how you could combine both arrays using a for loop:
const arr3 = []
for (let i = 0; i < arr1.length; i++) {
arr3[i] = {
name: arr1[i].name,
surname: arr2[i].surname
}
}
I don't get exactly what do you want to do but I think this question has been answered a few times.
You wanna do arr1 + arr2 ? Like they follow each others in the array3 ?
It feels like push is behaving funny. Rather than just push to 1 index inside the forEach, it seems to be pushing to all 3 indexes. Am I missing something obvious?
let arrayToReduce = [ [ 1, 2, 3 ] ]
let reduced = arrayToReduce.reduce((arr, inner) => {
const copied = arr.slice()
inner.forEach((num, idx) => {
copied[idx].push(num)
})
return copied
}, Array(arrayToReduce[0].length).fill([]))
console.log(reduced)
Expected output: [[1], [2], [3]]
Actual output: [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
push isn't the culprit, it is fill.
You've created an array the same length as the original and then filled it with a value.
That value is an array.
The same array.
So when you push a value to copied[0] you get a reference to that array and put a value into it.
And when you push a value to copied[1] you get a reference to that same array and put another value into it.
let arr = [ [ 7, 3, 47 ] ]
let reduced = arr.flat().map(e=>[e])
console.log(reduced)
//output: [[7], [3], [47]]
if you want your Expected output : [[1], [2], [3]]
Simply return index instead of item in inner array
let arr = [ [ 7, 3, 47 ] ]
let reduced = arr.flat().map((e,i)=>[i+1])
console.log(reduced)
In C# if I had a list for example of 3 ints [1,2,3], I could trasform that list into another with .Select in following way [1,2,3].Select(e => new { Id = e, Name = $"name:{e}"), which would return new array with 3 objects.
how can I get the same result in js without using for loop?
You can use the map function like this:
var array = [1,2,3]
var result = array.map(e => ({id: e, name: `name:${e}`}))
console.log(result)
It returns the following result:
[ { id: 1, name: 'name:1' },
{ id: 2, name: 'name:2' },
{ id: 3, name: 'name:3' } ]
Here is the map function docs:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Yes, it is called map(example with integers, but you can map into objects too):
const array1 = [1, 4, 9, 16];
const map1 = array1.map(x => x * 2);
console.log(map1);
// expected output: Array [2, 8, 18, 32]
I'm a Javascript beginner (more or less).
I've created a new array:
var genres = [
"metal",
"rockroll",
"funk",
"punk",
"country",
];
However, I'd like to put each genre in the array a specific number of times, not just once. I know I can just repeat each line as many times as I need, but I'm sure there's a better way.
It would be great if I could do something like this:
var genres = [
"metal" * 3,
"rockroll" * 5,
"funk" * 1,
"punk" * 0,
"country" * 4,
];
...but of course I've tried that, and it doesn't work.
Can anyone help me out? I wasn't able to find anything by googling.
Thanks!
You can build an array like this with reduce() if you start with some data structure that holds your counts and categories:
let cats = [[3, "metal"], [5, "rockroll"], [1, "funk"], [0, "punk"], [4, "country"] ]
// etc..
let arr = cats.reduce((arr, [n, cat]) => arr.concat(Array(n).fill(cat)), [])
console.log(arr)
let item = [
{
genres: "metal",
count: 3
},
{
genres: "rockroll",
count: 5
},
{
genres: "funk",
count: 1
},
{
genres: "punk",
count: 0
}
];
console.log(item);
item.map(i => {
for(let n = 0; n < i.count; n++){
console.log(i.genres);
}
});
How do you think about using the Object?
There's no built-in way to do this, but you could easily write a function to do it. For instance:
function addMultiples (input) {
const output = []
for (let key in input) {
for (let i = 0; i < input[key]; i++) {
output.push(key)
}
}
return output
}
Then you would pass in your values as an object:
console.log(addMultiples({
"metal": 3,
"rockroll": 5,
"funk": 1,
"punk": 0,
"country": 4
}).join(", "))
// prints "metal, metal, metal, rockroll, rockroll, rockroll, rockroll, rockroll, funk, country, country, country, country"
You can also use Array.from and keep your sub arrays filled. And only spread them when needed:
let cats = [[3, "metal"], [5, "rockroll"], [1, "funk"], [0, "punk"], [4, "country"]]
const filled = Array.from(cats, ([v,k]) => new Array(v).fill(k)) // fill arrays
console.log(filled.reduce((r,c) => [...r, ...c])) // spread for output