I have the following json returned from an ajax request
[
{
"id": "1",
"task": "eat pizza",
"username": "all"
},
{
"id": "2",
"task": "drink soda",
"username": "all"
}
]
I am trying to add specific pieces of data from the json to an existing js array.
this.$todoData2 = [
{
'id': '5',
'text': 'Cheese',
'done': false
},
]
I need to add json key id and its matching value - example: "id": key,
I need to add json key task as text with its matching value - example: "text": key
I need to add a "done": "false" to set so a final result would look like:
this.$todoData2 = [
{
"id": "1",
"text": "eat pizza",
'done': false
}
{
"id": "2",
"text": "drink soda",
'done': false
}
{
'id': '5',
'text': 'Cheese',
'done': false
},
]
I have no examples of what I have tried as I am not sure where to even begin with this. Keep in mind that json may contain a lot more results.
Use .forEach() to iterate over the 'updates' Array, while destructuring the key / value pairs you want to use
Create your object, then .push() it to the Array
const $todoData2 = [
{'id': '5', 'text': 'Cheese', 'done': false},
];
const update = [
{"id": "1", "task": "eat pizza", "username": "all"},
{"id": "2", "task": "drink soda", "username": "all"}
];
update.forEach(({id, task}) => {
$todoData2.push({
'id': id,
'text': task,
'done': false
});
});
console.log($todoData2);
You can merge both arrays and then use map.
let arr = [
{
"id": "1",
"task": "eat pizza",
"username": "all"
},
{
"id": "2",
"task": "drink soda",
"username": "all"
}
]
let todoData2 = [
{
'id': '5',
'text': 'Cheese',
'done': false
},
]
todoData2 = todoData2.concat(arr).map( obj => ({ id:obj.id, text:obj.task || obj.text , done:false }) );
console.log(todoData2)
If the point here is to simply append and rename keys, it may by done as simple as that:
const newItems = [{"id":"1","task":"eat pizza","username":"all"},{"id":"2","task":"drink soda","username":"all"}],
existingItems = [{"id":"5","text":"Cheese","done":false}]
existingItems.push(...newItems.map(({id,task:text}) => ({id,text,done:false})))
console.log(existingItems)
.as-console-wrapper{min-height:100%}
Related
I have 2 arrays containing objects, I want to create a new array without "duplicates". The problem is that the two arrays are not identical and I want to choose based on id.
This is a simple version of what I got:
let array1 = [
{
"id": "1",
"type": "abc"
},
{
"id": "2",
"type": "one, two, three"
}
]
let array2 = [
{
"id": "1",
"type": "abc",
"country": "England"
},
{
"id": "3",
"type": "one, two, three",
"country": "Germany"
}
]
let array3 = array1.filter(x => array2.forEach(y => x.id === y.id)).concat(array2);
The result I want for array3 is:
{
"id": "1",
"type": "abc"
}
In this particular case country is not important and will be thrown away anyway.
How do I filter out unwanted objects and create a new array with only the objects I want?
If you are looking for an intersection between the arrays the shortest answer is to use the filter with a find.
let array1 = [{
id: '1',
type: 'abc',
},
{
id: '2',
type: 'one, two, three',
},
];
let array2 = [{
id: '1',
type: 'abc',
country: 'England',
},
{
id: '3',
type: 'one, two, three',
country: 'Germany',
},
];
const array3 = array1.filter(value => array2.find((a)=>a.id==value.id));
console.log(array3);
let array1 = [{
id: '1',
type: 'abc',
},
{
id: '2',
type: 'one, two, three',
},
];
let array2 = [{
id: '1',
type: 'abc',
country: 'England',
},
{
id: '3',
type: 'one, two, three',
country: 'Germany',
},
];
array2.forEach((el, idx) => {
const match = array1.find((el2) => el2.id === el.id);
if (!match) array1.push(el);
});
console.log(array1);
Something like this ? I assumed from your explanation that you want to merge array2 with array1.
You will end up with the unique objects from array2 having the extra country property, if you want to delete that you need an extra step before pushing.
I think this is what you were trying to achieve:
let array1 = [ { "id": "1", "type": "abc" }, { "id": "2", "type": "one, two, three" } ];
let array2 = [ { "id": "1", "type": "abc", "country": "England" }, { "id": "3", "type": "one, two, three", "country": "Germany" } ];
let array3 = array1.filter(x => array2.map(y => y.id).includes(x.id));
console.log( array3 );
In order to avoid have to recompute the array2 array of ids you can get them in advance as follows:
let array1 = [ { "id": "1", "type": "abc" }, { "id": "2", "type": "one, two, three" } ];
let array2 = [ { "id": "1", "type": "abc", "country": "England" }, { "id": "3", "type": "one, two, three", "country": "Germany" } ];
const ids = array2.map(({id}) => id);
let array3 = array1.filter(x => ids.includes(x.id));
console.log( array3 );
I'm trying to go through this JSON object and grab some values out of it.
let currentPage = "
{
"sys": {
"space": {
"sys": {
"type": "Link",
"linkType": "Space",
"id": "xaswoie0ncrg"
}
},
"id": "7lqAYzwP92G9TMDBUVnadp",
"type": "Entry",
"createdAt": "2020-07-30T18:08:33.159Z",
"updatedAt": "2020-07-30T18:22:50.276Z",
"environment": {
"sys": {
"id": "master",
"type": "Link",
"linkType": "Environment"
}
},
"revision": 2,
"contentType": {
"sys": {
"type": "Link",
"linkType": "ContentType",
"id": "landingPage"
}
},
"locale": "en-US"
},
"fields": {
"pageTitle": "Leading the next generation of renewable fuels",
"heroImage": {
"sys": {
"type": "Link",
"linkType": "Asset",
"id": "vnjfnYzSyhqOjKlmNmBGb"
}
},
"pageZone": [
{
"sys": {
"type": "Link",
"linkType": "Entry",
"id": "3aQvORUYowW0SoofuvHUov"
}
},
{
"sys": {
"type": "Link",
"linkType": "Entry",
"id": "Qfj1hNJ9euSkBcAQEDaN5"
}
}
]
}
}"
I then parse the JSON:
let currentPage2 = JSON.parse(currentPage);
Now here's the issue.
If log this in the console:
console.log(Object.keys(currentPage2.fields.pageZone[0].sys.id));
Node returns this in the terminal:
[
'0', '1', '2', '3', '4',
'5', '6', '7', '8', '9',
'10', '11', '12', '13', '14',
'15', '16', '17', '18', '19',
'20', '21'
]
I want to use this:
console.log(Object.keys(currentPage2.fields.pageZone[0].sys.id).value);
//with expected value of "3aQvORUYowW0SoofuvHUov"
Instead, it returns undefined. I have no idea why this is happening. I have tried using JSON.stringify etc and parsing it again, but it still behaves this way.
Just use currentPage2.fields.pageZone[0].sys.id. There is no need for Object.keys at all, unless you want each index of the string.
currentPage2.fields.pageZone[0].sys.id is a string, and since Object.keys will interpret the string as an iterable, the keys will be the indexes of each characters.
I have an an array of objects. My objective is to remove objects that contain keys with empty arrays.
I am using ramda, but am hitting a wall at the moment.
const myData = {
"one": {
"two": {
"id": "1",
"three": [{
"id": "33",
"copy": [{
"id": "1",
"text": "lorem",
"answer": [],
},
{
"id": "2",
"text": "ipsum",
"answer": [{
"id": 1,
"class": "science"
}]
},
{
"id": "3",
"text": "baesun",
"answer": [{
"id": 2,
"class": "reading"
}]
}
],
}]
}
}
}
flatten(pipe(
path(['one', 'two', 'three']),
map(step => step.copy.map(text => ({
answers: text.answer.map(answer => ({
class: answer.class,
})),
}), ), ))
(myData))
This the result:
[{"answers": []}, {"answers": [{"class": "science"}]}, {"answers": [{"class": "reading"}]}]
This is the expectation:
[{"answers": [{"class": "science"}]}, {"answers": [{"class": "reading"}]}]
Get the the array of inside three with path, chain the arrays inside the copy properties, and project them to contain only answer. Reject empty answers, and then evolve the objects inside each answer to contain only the class property.
const {pipe, path, chain, prop, project, reject, propSatisfies, isEmpty, map, evolve} = ramda
const transform = pipe(
path(['one', 'two', 'three']), // get the array
chain(prop('copy')), // concat the copy to a single array
project(['answer']), // extract the answers
reject(propSatisfies(isEmpty, 'answer')), // remove empty answers
map(evolve({ answer: project(['class']) })) // convert the objects inside each answer to contain only class
)
const data = {"one":{"two":{"id":"1","three":[{"id":"33","copy":[{"id":"1","text":"lorem","answer":[]},{"id":"2","text":"ipsum","answer":[{"id":1,"class":"science"}]},{"id":"3","text":"baesun","answer":[{"id":2,"class":"reading"}]}]}]}}}
const result = transform(data)
console.log(result)
<script src="//bundle.run/ramda#0.26.1"></script>
use filter
const filter = R.filter,
flatten = R.flatten,
pipe = R.pipe,
path = R.path,
map = R.map;
const myData = {
"one": {
"two": {
"id": "1",
"three": [{
"id": "33",
"copy": [{
"id": "1",
"text": "lorem",
"answer": [],
},
{
"id": "2",
"text": "ipsum",
"answer": [{
"id": 1,
"class": "science"
}]
},
{
"id": "3",
"text": "baesun",
"answer": [{
"id": 2,
"class": "reading"
}]
}
],
}]
}
}
}
const result = filter(answersObj => answersObj.answers.length, flatten(pipe(
path(['one', 'two', 'three']),
map(step => step.copy.map(text => ({
answers: text.answer.map(answer => ({
class: answer.class,
}))
})))
)(myData)))
console.log(result);
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
So i have an array which stores hobbies for each user in an array within the object..
var hobbies = [
{
"id": 1,
"hobbies": []
},
{
"id": 2,
"hobbies": [
"football"
]
},
{
"id": 3,
"hobbies": [
"football",
"basketball"
]
}
]
What i want to return is a new array of objects but each hobby separated into their own object like below.
var result = [
{
"id": 2,
"hobby": "football"
},
{
"id": 3,
"hobby": "football"
},
{
"id": 3,
"hobby": "basketball"
}
]
What is have so far is
hobbies.filter((f, i) => f.hobbies.length > 0).map((p, i) => {
while (i < p.hobbies.length) {
return { id : p.id, hobby : p.hobbies[i] };
}
});
which only returns
[
{
"id": 2,
"hobby": "football"
},
{
"id": 3,
"hobby": "basketball"
}
]
You can use array#reduce with array#map. Iterate through each object and then iterate through each hobby of hobbies and create the object.
var hobbies = [ { "id": 1, "hobbies": [] }, { "id": 2, "hobbies": [ "football" ] }, { "id": 3, "hobbies": [ "football", "basketball" ] } ],
result = hobbies.reduce((r, {id, hobbies}) => r.concat(hobbies.map(hobby => ({id, hobby}))), []);
console.log(result);
I know, "functional" programming is considered "cool" around these parts, however, have you considered using simple loops to, well, loop over your data?
let result = [];
for (let {hobbies, id} of data)
for (let hobby of hobbies)
result.push({id, hobby})
In my opinion, this is far more readable than any reduce spaghetti one could come up with ;)
You need to use inner-loop to loop through the hobbies and push them one-by-one to the target array:
var hobbies = [{
"id": 1,
"hobbies": []
},
{
"id": 2,
"hobbies": [
"football"
]
},
{
"id": 3,
"hobbies": [
"football",
"basketball"
]
}
];
var result = hobbies.reduce((acc, item) => {
item.hobbies.forEach(hobby => {
acc.push({
id: item.id,
hobby: hobby
});
});
return acc;
}, []);
console.log(result);
You can use array.prototype.reduce:
var hobbies = [{"id": 1,"hobbies": []},{"id": 2,"hobbies": ["football"]},{"id": 3, "hobbies": ["football","basketball"]}];
var res = hobbies.reduce((m, o) => (o.hobbies.forEach(h => m.push({id: o.id, hobby: h})), m), []);
console.log(res);
You need nested loops and this is the basics of it:
You first need to loop over the main hobbies array.
Then for each item in the array (which represents a person), you want to loop through their hobbies, and for each one of those hobbies, you need to push an object made up of the profile ID and the hobby into results array I created earlier.
var hobbies = [{ "id": 1, "hobbies": [] }, { "id": 2, "hobbies": [ "football" ] }, { "id": 3, "hobbies": [ "football", "basketball" ] } ];
let result = [];
hobbies.forEach(function(profile){
profile.hobbies.forEach(function(hobby){
result.push(
{
"id": profile.id,
"hobby": hobby
}
);
});
});
console.log(result)
Update: the other answers with Array.reduce (a more specialised loop) will cut the above code down even further.
I have this data set in object, keys are strings
{ '17': '17-17:30',
'20': '20:00-21',
'21': '21-22',
'22': '22-23',
'23': '23-24',
'01': '1-2',
'02': '2-3',
'03': '3-4',
'04': '4-5',
'05': '5-6',
'06': '6-7',
'07': '7-7:30',
'08': '08:50-9' }
I want to arrange them numerically so that 01 comes first and 23 comes last.
Here's the code I'm using:
var sort_object = function(map) {
var keys = _.sortBy(_.keys(map), function(a) { return Number(a); });
var newmap = {};
_.each(keys, function(k) {
newmap[k] = map[k];
});
return newmap;
}
it still returns 17 in the beginning.
Where did I go wrong?
As Blender pointed out, objects are not ordered. You need to use an array. There are several ways you could set up this array, and once you have the data in an array it's very easy to sort it.
Here are a couple of examples. First, let's try making this an array of arrays. The outer array is the list of elements, and each element of this array is itself an array of two elements, your key and your value.
So paste this code into your favorite JavaScript console, such as the one in Chrome:
var data = [
[ '17', '17-17:30' ],
[ '20', '20:00-21' ],
[ '21', '21-22' ],
[ '22', '22-23' ],
[ '23', '23-24' ],
[ '01', '1-2' ],
[ '02', '2-3' ],
[ '03', '3-4' ],
[ '04', '4-5' ],
[ '05', '5-6' ],
[ '06', '6-7' ],
[ '07', '7-7:30' ],
[ '08', '08:50-9' ]
];
var result = data.slice().sort( function( a, b ) {
return +a[0] - +b[0];
});
JSON.stringify( result, null, 4 );
It will log:
[
[
"01",
"1-2"
],
[
"02",
"2-3"
],
[
"03",
"3-4"
],
[
"04",
"4-5"
],
[
"05",
"5-6"
],
[
"06",
"6-7"
],
[
"07",
"7-7:30"
],
[
"08",
"08:50-9"
],
[
"17",
"17-17:30"
],
[
"20",
"20:00-21"
],
[
"21",
"21-22"
],
[
"22",
"22-23"
],
[
"23",
"23-24"
]
Or, instead of an array of arrays, you can use an array of objects. This is often more convenient to work with. Paste this code into the JavaScript console:
var data = [
{ key: '17', value: '17-17:30' },
{ key: '20', value: '20:00-21' },
{ key: '21', value: '21-22' },
{ key: '22', value: '22-23' },
{ key: '23', value: '23-24' },
{ key: '01', value: '1-2' },
{ key: '02', value: '2-3' },
{ key: '03', value: '3-4' },
{ key: '04', value: '4-5' },
{ key: '05', value: '5-6' },
{ key: '06', value: '6-7' },
{ key: '07', value: '7-7:30' },
{ key: '08', value: '08:50-9'}
];
var result = data.slice().sort( function( a, b ) {
return +a.key - +b.key;
});
JSON.stringify( result, null, 4 );
It will log:
[
{
"key": "01",
"value": "1-2"
},
{
"key": "02",
"value": "2-3"
},
{
"key": "03",
"value": "3-4"
},
{
"key": "04",
"value": "4-5"
},
{
"key": "05",
"value": "5-6"
},
{
"key": "06",
"value": "6-7"
},
{
"key": "07",
"value": "7-7:30"
},
{
"key": "08",
"value": "08:50-9"
},
{
"key": "17",
"value": "17-17:30"
},
{
"key": "20",
"value": "20:00-21"
},
{
"key": "21",
"value": "21-22"
},
{
"key": "22",
"value": "22-23"
},
{
"key": "23",
"value": "23-24"
}
]
Either way, as you can see, once you have your data in a suitable format (i.e. the data as a whole needs to be an array), then it becomes very simple to sort it.
Let's look at that sort function in more detail (using the second example):
var result = data.slice().sort( function( a, b ) {
return +a.key - +b.key;
});
In this code a.key gets the value for the key property of one of the array elements. The + in front of that converts the string to a number - much like using the Number function but a simpler way to do it. Similarly for +b.key. And then subtracting those two numbers gives the correct sort function return: a positive, negative, or zero value depending on whether a.key or b.key is the greater of the two or if they're equal.
The first example works similarly, just using +a[0] - +b[0] instead of +a.key - +b.key.
The .slice() call in each example makes a copy of the array. You could omit that if you want to sort the original array.
The only way to imply order would be to use an array. How about an array of key/value objects, eg
return Object.keys(map).sort().map(function(k) {
return {key: k, value: foo[k]}
});