Split object into two properties [duplicate] - javascript

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);

Related

Remove all keys that have the same value in array

I need to remove all keys except last inserted that have the same value on key id_ask in array but I'm learning javascript and I still do not know how to do this.
jQuery(function()
{
let arr = []
let q = []
$("body").on('click', '.link_resposta', function(event)
{
event.preventDefault();
/* Act on the event */
let id_poll = $(this).data("idpesquisa")
let id_ask = $(this).data("idpergunta")
let id_anwser = $(this).children("li").data("idresposta")
let q = {
id_poll,
id_ask,
id_anwser
}
arr.push(q)
console.log(arr)
});
});
Using a combination of Set, Array.reverse() and Array.map we can solve this easily.
We first use the Set and we map our source array in, just feeding the id_ask field. From that we get an array of unique id_ask.
We then map the unique id_ask array and for each id_ask we call a find() on the source array in reverse.
Comments inline.
const sampleArray = [
{
id: 1,
id_ask: 2,
id_answer: 3
},
{
id: 2,
id_ask: 2,
id_answer: 5
},
{
id: 3,
id_ask: 3,
id_answer: 3
},
{
id: 4,
id_ask: 3,
id_answer: 1
},
{
id: 5,
id_ask: 4,
id_answer: 3
}
];
// Create a unique Set of Ask ID
const uniqueAskId = [...new Set(sampleArray.map(e => e.id_ask))];
console.log(uniqueAskId);
// Use Map and Reverse to get last item.
const r = uniqueAskId.map(uid => sampleArray.reverse().find(ask => ask.id_ask === uid));
console.log(r);
Here it is as a single statement:
const sampleArray = [
{
id: 1,
id_ask: 2,
id_answer: 3
},
{
id: 2,
id_ask: 2,
id_answer: 5
},
{
id: 3,
id_ask: 3,
id_answer: 3
},
{
id: 4,
id_ask: 3,
id_answer: 1
},
{
id: 5,
id_ask: 4,
id_answer: 3
}
];
// put together in a single statement.
const result = [...new Set(sampleArray.map(e => e.id_ask))]
.map(uid => sampleArray.reverse().find(ask => ask.id_ask === uid));
console.log(result);
NOTE: For large datasets it would obviously be more efficient to call the reverse() one time before you use.
const revArray = myArray.reverse();
const resultArray = [...new Set(revArray.map(e => e.id_ask))]
.map(uid => revArray.reverse().find(ask => ask.id_ask === uid));

Manipulate object property of an array [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I have an array of objects with some property. I wanted to do some math on the object property, and expect to return an array as well.
I've tried, doesn't seems to work.
array.map(el => {
el.count * 2;
return el
})
array = [{
count: 4,
string: 'randomstring'
}, {
count: 9,
string: 'randomstring'
}, {
count: 7,
string: 'randomstring'
}, {
count: 12,
string: 'randomstring'
}]
Expected
array = [{
count: 8,
string: 'randomstring'
}, {
count: 18,
string: 'randomstring'
}, {
count: 14,
string: 'randomstring'
}, {
count: 24,
string: 'randomstring'
}]
el.count * 2; will not change the value of el.count You could assign it to it like
el.count = el.count * 2;
But this will create another problem. It will change the original data. So better to return a new object with modified count property using Spread Operator
let array = [{ count: 4, string: 'randomstring' }, { count: 9, string: 'randomstring' }, { count: 7, string: 'randomstring' }, { count: 12, string: 'randomstring' }]
let res = array.map(el => ({...el,count:el.count*2}));
console.log(res);
You can also you Object.assign()
let res = array.map(el => Object.assign({count:el.count*2}));
You could map independent objects without mutating the original array.
newArray = array.map(o => Object.assign({}, o, { count: o.count * 2 }));
The same with spreading the object.
newArray = array.map(o => ({ ...o, count: o.count * 2 }));
Without explicitly mutating object's value (that's why we use map, filter and reduce in the first place):
array.map(({ count, string }) => (
{ count: count * 2, string }
));
try
array.map(e=>(e.count*=2,e))
let array = [
{ count: 4, string: 'randomstring' },
{ count: 9, string: 'randomstring' },
{ count: 7, string: 'randomstring' },
{ count: 12, string: 'randomstring' }
];
let r = array.map(e=>(e.count*=2,e))
console.log(r);

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

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)

relative complement of A in B with functional programming

I have to retrieve the values that exist only on Array B, but do not exist on Array A.
From my research, It is called:
relative complement of A in B
Values in the arrays may not be primitives.I need an efficient and functional apporach to this problem.
I have found lodash _.without function, but it supports only array of primitive numbers.
Array A:
[{
id: 1
},
{
id:2
}]
Array B:
[{
id:2
},
{
id:3
}]
result should be:
[{
id:3
}]
this object is the only one who exist on Array B, but not on Array A.
You could use a comparison function which takes two objects and check the id for unequalness.
var aa = [{ id: 1 }, { id: 2 }],
bb = [{ id: 2 }, { id: 3 }],
comparison = (a, b) => a.id !== b.id,
result = bb.filter(b => aa.every(a => comparison(a, b)));
console.log(result);
With a check for equalness
var aa = [{ id: 1 }, { id: 2 }],
bb = [{ id: 2 }, { id: 3 }],
comparison = (a, b) => a.id === b.id,
result = bb.filter(b => aa.every(a => !comparison(a, b)));
console.log(result);
You can use array#filter with array#some. Iterate through arrB and check if the arrA contains that id using array#some and negate the result of array#some.
var arrA = [{id: 1},{id:2}],
arrB = [{id:2},{id:3}],
result = arrB.filter(({id}) => !arrA.some(o => o.id === id));
console.log(result);
You can use array.prototype.filter and array.prototype.findIndex:
var arrayA = [{ id: 1 }, { id: 2 }];
var arrayB = [{ id: 2 }, { id: 3 }];
var result = arrayB.filter(b => arrayA.findIndex(a => a.id === b.id) === -1);
console.log(result);
If you want to use lodash, _.differenceBy could be of use:
relativeComplementOfAinB = _.differenceBy(arrayB, arrayA, v => v.id);

Combine object and arrays

I'm trying to write a function that takes an array of objects, and an unlimited number of arrays, and combines them to form a single object. The inputs would follow this pattern:
let x = [{ name: 'Tom' }, { name: 'John' }, { name: 'Harry' }];
let y = [[1, 2, 3], 'id'];
let z = [['a', 'b', 'c'], 'value'];
combine(x, y, z);
With the second element of y and z acting as the object key. Using these arguments, the function should return the following array:
[
{
name: 'Tom',
id: 1,
value: 'a'
},
{
name: 'John',
id: 2,
value: 'b'
},
{
name: 'Harry',
id: 3,
value: 'c'
},
]
The index of the current object should be used to get the correct element in the array. I have made an attempt at the problem:
function combine(object, ...arrays) {
return object.map((obj, index) => {
let items = arrays.map(arr => ({
[arr[1]]: arr[0][index]
}));
return Object.assign({}, obj, { items });
});
}
This almost does the job, but results in the array items being hidden inside a nested items array, How can I solve this?
You had been assigning an object of object, and the result was a new object with the element items inside (another feature of object literal).
This approach use reduce instead of map and direct assign instead of object literal.
function combine(object, ...arrays) {
return object.map((obj, index) => {
const items = arrays.reduce((acc, arr) => {
acc[arr[1]] = arr[0][index] ;
return acc;
}, {});
return Object.assign({}, obj, items);
});
}
const x = [{ name: 'Tom' }, { name: 'John' }, { name: 'Harry' }];
const y = [[1, 2, 3], 'id'];
const z = [['a', 'b', 'c'], 'value'];
combine(x, y, z);
You can also use the spread operator in the Object.assign, like this:
function combine(object, ...arrays) {
return object.map((obj, index) => {
let items = arrays.map(arr => ({
[arr[1]]: arr[0][index]
}));
return Object.assign({}, obj, ...items);
});
}
This almost does the job, but results in the array items being hidden inside a nested items array
The problem is that items is an array, whereas you only need the current item inside of that particular map callback. No need to nest loops here.
Also I would recommend avoiding multiple properties per combine call. The resulting code would look like this:
function combine(objects, [values, key]) {
return objects.map((o, i) =>
Object.assign({[key]: values[i]}, o)
);
}
combine(combine(x, y), z);
If you then have multiple extensions to do, you can also use
[y, z].reduce(combine, x)
With map and computed keys, you can achieve this.
Here's a working example:
let x = [{
name: 'Tom'
}, {
name: 'John'
}, {
name: 'Harry'
}];
let y = [[1, 2, 3], 'id'];
let z = [['a', 'b', 'c'], 'value'];
let result = [];
x.map(function (el, index) {
result.push(el);
let index = result.length -1;
result[index][y[1]] = y[0][index];
result[index][z[1]] = z[0][index];
});
console.log(result);

Categories

Resources