Select only specific properties from an array of objects [duplicate] - javascript

This question already has answers here:
Extract certain properties from all objects in array
(5 answers)
Closed 4 months ago.
Let's say I create object like this:
updates.push({
id: this.ids[i],
point: point,
value: value
});
Later on I want to use JSON.stringify on updates object, however I need only
point and value like:
updates[{point: 1, value: 12}, {point: 2, value: 24}]
What's the best ES6 solution for that?
I looked at some examples with delete, but that's not what I actually need, as I do not want to delete ids.

Try the following :
JSON.stringify(updates.map(({point,value})=>({point,value})));
let updates = [{id : 1, point : 1, value: 2},{id : 1, point : 1, value: 2}];
console.log(JSON.stringify(updates.map(({point,value})=>({point,value}))));

If updates is an array. Then you might want something like this:
const newArrayWithoutId = updates.map(({ point, value }) => {
return {
point,
value,
}
}

Just ({id, ...rest}) => ({...rest}) is too short for an answer, so how about this?
const withoutId = ({id, ...rest}) => ({...rest})
const vals = [
{id: 'a', point: 1, value: 'foo'},
{id: 'b', point: 2, value: 'bar'},
{id: 'c', point: 3, value: 'baz', meaning: 42}
]
const reduced = vals.map(withoutId)
console.log(reduced)

Related

JS sort by predefined string values [duplicate]

This question already has answers here:
Javascript - sort array based on another array
(26 answers)
Sorting an Array of JavaScript Objects a Specific Order (using existing function)
(6 answers)
Closed 2 years ago.
I have an array of items that I want to sort based on the category property:
const arr = [{
id: 1,
category: 'bar'
}, {
id: 4,
category: 'baz'
},
{
id: 5,
category: 'foo'
}]
What I want is to sort it based on the following order:
- foo
- bar
- baz
How can I do it with an array comparator?
arr.sort(function(a, b) {
return ?
})
Do I need to give each category an order number and do a.order - b.order? Or there is another clever way to do it?
You can put your order into an array and use indexOf within sort.
const arr = [{
id: 1,
category: 'bar'
}, {
id: 4,
category: 'baz'
},
{
id: 5,
category: 'foo'
}]
const order = ["foo","bar","baz"]
arr.sort( (a,b) => order.indexOf(a.category) - order.indexOf(b.category) )
console.log(arr)

How to remove object from object of objects in javascript

I have an object as follows:
let object = {
1: {id: 1, name: "One"},
2: {id: 2, name: "Two"},
3: {id: 3, name: "Three"}
}
And I want to remove one of them, for example the object with id 2
Now I do it using lodash as follows:
forOwn(object, function(value, key) {
value.id === 2 && delete object[key]
});
That does the trick but is it the right way?
You can use UnderscoreJs Library
let object = {
1: {id: 1, name: "One"},
2: {id: 2, name: "Two"},
3: {id: 3, name: "Three"}
}
let newobject=_.remove(object,function(nv){
return nv.id===3;
});
the above code will delete the object having id=3 and return
{
1: {id: 1, name: "One"},
2: {id: 2, name: "Two"},
}
I think you're not getting the answers you're looking for, because maybe you've over simplified the use-case, so it's tempting to just say:
delete object[2]; // which modifies the original object
If your data is not that static, or if you want to do something more complex to remove certain elements, you could do something similar to this:
const relevantObjects = Object.entries(object) // converts each entry to [key, value]
.filter(([k, v]) => v.id !== 2) // define the criteria to include/exclude items
.reduce((acc, [k, v]) => {
acc[k] = v;
return acc; // this function can be improved, it converts the [[k, v]] back to {k: v, k: v, ...}
}, {});
Edit:
It's perfectly fine to use a lib or whatever. Everything has its pros & cons, just do whatever works for you <3
I would use a simple for ... in instead of loadash
let object = {
1: {id: 1, name: "One"},
2: {id: 2, name: "Two"},
3: {id: 3, name: "Three"}
}
let deleteById = (obj,idToRemove) => {
for(let key in obj){
let {id} = obj[key] | {}
if(id === idToRemove){
delete obj[key]
}
}
}
deleteById(object,2)
console.log(object)
This is the right way. To do it in JSON you do the following:
var json = { ... };
var key = "foo";
delete json[key];
So if you swap out json to object you are all set.

Best way to modify Array: Array 1 has X values. Array 2 has a subset of these. Modify every object that matches Array 2 javascript

I have two arrays:
array1 = [{ id: id1, value: false}, {id: id2, value: false}, id: id3, value: false}]
array2 = [id1, id2]
What I want to do is compare these two, and for every match on ID in array2, I want to set the value to true. So in the example above, I would like to modify my array1 (or create a new one) to:
array1 = [{ id: id1, value: true}, {id: id2, value: true}, {id: id3, value: false}]
Both arrays are dynamically created, I don't know their size. But array2 is never larger than array1, and array2 can also be empty.
Today I have solved this by doing a double for each:
array1.forEach(element => {
array2.forEach(element2 => {
if (element.id== element2) {
element.value= true;
}
});
});
But I believe that this can be done in a much better way? I feel that the .map() function may help me out here, but I haven’t grasped it fully yet.
Bonus question, array2 is in fact just a string that looks like this: "id1; id2". I convert it to an array with var array2 = string.split(";"); Is there a smoother way to just compare the whole string to array1 instead of creating an array out of it?
You can use Array#map function for creating a different array (you can also use Array#forEach to change the current one) and in the condition use Array#includes to check if the second array contains the item's id.
I also have used object destructuring (...) to create another item objects int the mapped array to have entirely different array with different items.
const array1 = [
{ id: 'id1', value: false},
{ id: 'id2', value: false},
{ id: 'id3', value: false}]
const array2 = ['id1', 'id2'];
const mapped = array1.map(item => array2.includes(item.id) ? { ...item, value: true } : {...item});
console.log(mapped);
You're right about the possible performance issues. If arrays 1 and 2 have M and N values, it will take M×N operations to iterate through every possible pair. This might take a long time if both M and N are large. However, it looks like each element in array 1 has a unique ID. If this is the case, one option is to use a map (sometimes called a dictionary or associative array) instead of an array to index the values by ID, and then modify them if necessary.
const array1 = [{ id: id1, value: false}, {id: id2, value: false}, id: id3, valu;e: false}]
const array2 = [id1, id2];
// Use a plain object as a map.
const array1byID = {};
array1.forEach((val) => { array1byID[val.id] = val; });
// Modify the values in the object
array2.forEach((ary2ID) => {
if (array1byID has ary2ID) {
array1byID[ary2ID].value = true;
}
});
// array1 will now be updated since it shares elements with array1byID.
This will only take N operations.
If the entries in array 1 don't have unique IDs, you're better of using a Set to store the values of array 2. A Set can test if an element is included using Set.has() much faster than an array can using indexOf() or find(). In that case, the code would be:
const array1 = [{ id: id1, value: false}, {id: id2, value: false}, id: id3, valu;e: false}]
const array2 = [id1, id2];
// Use a plain object as a map.
const set2 = new Set(array2);
array1.forEach((el) => {
if (set2.has(el.id)) {
el.value = true;
}
});
If you have a lot of arrays of things with IDs, you should probably consider using maps instead. A helpful explanation why can be found in the article You might not need arrays. The title exaggerates the case a little bit, but if you're just doing create-update-delete stuff, the ideas are well worth exploring.
You could use Array#find for getting the object for an update.
var array1 = [{ id: 'id1', value: false }, { id: 'id2', value: false }, { id: 'id3', value: false }],
array2 = ['id1', 'id2'];
array2.forEach(i => array1.find(({ id }) => id === i).value = true);
console.log(array1);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using your own code, with indexOf():
array1 = [{ id: 1, value: false}, {id: 2, value: false}, {id: 3, value: false}];
array2 = [1, 2];
array1.forEach(element => {
if (array2.indexOf(element.id) != -1) {
element.value= true;
}
});
console.log(array1);
You can use .includes() too:
array1 = [{ id: 1, value: false}, {id: 2, value: false}, {id: 3, value: false}];
array2 = [1, 2];
array1.forEach(element => {
if (array2.includes(element.id)) {
element.value= true;
}
});
console.log(array1);

Split object into two properties [duplicate]

This question already has answers here:
Convert object to array of key–value objects like `{ name: "Apple", value: "0.6" }`
(3 answers)
Closed 1 year ago.
a very beginner question below I'm sure, apologies for asking but I've had a good hunt on the matter with no luck... I'm looking to 'break' or 'expand' the following:
var words = { hello: 2, there: 3, heres: 1, text: 1 }
Into this:
var words = [{
word: 'hello',
count: 2
}, {
word: 'there',
count: 3
}, {
word: 'heres',
count: 1
}, {
word: 'text',
count: 1
}]
I've been messing around a lot with Underscore.js, but must be missing something very obvious. Any help will be greatly appreciated, thanks!
You can do this with Object.keys() and map().
var words = { hello: 2, there: 3, heres: 1, text: 1 }
var result = Object.keys(words).map(e => ({word: e, count: words[e]}))
console.log(result)
You can also first create array and then use for...in loop to push objects.
var words = { hello: 2, there: 3, heres: 1, text: 1 }, result = [];
for(var i in words) result.push({word: i, count: words[i]})
console.log(result)
Possible solution using Array#map.
const words = { hello: 2, there: 3, heres: 1, text: 1 },
res = Object.keys(words).map(v => ({ word: v, count: words[v] }));
console.log(res);
Or Array#reduce.
const words = { hello: 2, there: 3, heres: 1, text: 1 },
res = Object.keys(words).reduce((s,a) => (s.push({ word: a, count: words[a] }), s), []);
console.log(res);
Here's a solution using underscore's map function:
words = _.map(words, (v, k) => ({word: k, count: v}));
Underscore's map can iterate over an object. The first parameter to the iteratee is the value and the second parameter is the key.
let object = {
"06.10 15:00": 3.035,
"06.10 21:00": 3.001,
};
let arr = [];
for (const [key, value] of Object.entries(object)) {
arr.push({ date: key, value: value });
}
console.log(arr);

Filter the original array of objects by array of ids

I have two arrays:
array a:
var a = [
{
id: 1,
name: 'a'
},
{
id: 2,
name: 'b'
},
{
id: 3,
name: 'c'
}
];
array ids:
var ids = [1];
I want to array a filtered by array ids, result i wanted:
var a = [
{
id: 1,
name: 'a'
}
];
The most important thing is i want the change on the original array, rather than return a new array.
underscore solution is better:)
You can use .filter
a = a.filter(function(el){
return ~ids.indexOf(el.id)
});
// should give you [{id: 1, name: 'a'}]
Today I tried to solve similar task (filtering the original array of objects without creating a new array) and this is what I came up with:
const a = [{ id: 1, name: 'a'}, { id: 2, name: 'b'}, { id: 3, name: 'c'}];
const ids = [1];
Array.from(Array(a.length).keys()).reverse().forEach(index =>
!ids.some(id => id === a[index].id) && a.splice(index, 1)
);
console.log(a); // [{ id: 1, name: 'a'}]
The point is that we need to loop back through the original array to be able to use Array.prototype.splice, but I didn't want the for-loop, I wanted to have ES6 one-liner. And Array.from(Array(a.length).keys()).reverse() gives me a list of reversed indexes of the original array. Then I want to splice the original array by current index only if the corresponding item's id is not present in the ids array.

Categories

Resources