DynamoDB, BatchWriteItem for an array - AWS V3 - javascript

I have an array I am using to create a put for batchwriteitem.
const people = [{
location: 'London',
name: 'Tony Wilson',
pets: [ {name: 'Cuddles', age: 4}, { name: 'Jess', age: 2}]
},
{
location: 'Manchester',
name: 'Liz Smith',
pets: [ {name: 'Fluffy', age: 4}, { name: 'Keith the cat', age: 2}]
}
]
My batchwriteitem loop is working for individual items
location: { S : item.location },
but when I try and input the pets array as an array it fails
pets: { M: item.pets },
So this all works except the pets array.
const request = pets.map(item => {
const createdDate = Date.now();
return {
PutRequest: {
Item: {
location: { S : item.location },
createdDate:{ N: createdDate },
pets: { M: item.pets }
}
}
});
Do I need to break down the pets array into types and if so how can I achieve this?
Edit
pets: { L: item.pets }, does not work
**Cannot read properties of undefined (reading '0')
and the old syntax without the types does not work on v3 with the document client for me.

Pets is an array, which is also known as a list type. You are setting it as a dictionary/map type as you've set the value to M. It should be L:
pets: { L: item.pets },
I would advise that you use the Document Client as it means you do not need to think about the type conversions, and just use native JSON objects:
pets: item.pets,

Related

How to filter array of objects by another array of objects by property using javascript

I have two nested array of objects, how to compare two array of objects by
id from arrobj1 and assignId from arrobj2 using javascript
So, I would to know how to compare array of objects by id and assignId and return array of objects using javascript
Tried
const result = arrobj1.filter(arr1 => {
arrobj2.find(arr2 => arr2.assignId === arr1.id)
});
var arrobj1 =[
{id: 1, name: 'xxx', value:100},
{id: 2, name: 'yyy', value:200},
{id: 3, name: 'zzz', value:400}
]
var arrobj2 =[
{country: 'IN', name: 'lina', assignId:2},
{country: 'MY', name: 'john', assignId:3},
{country: 'SG', name: 'peter', assignId:6}
]
Expected Code:
[
{id: 2, name: 'yyy', value:200},
{id: 3, name: 'zzz', value:400}
]
You have it almost correct, but you need to return in your filter, either by explicitly adding the return keyword or by removing the braces to use the arrow function's implicit return:
const result = arrobj1.filter(arr1 =>
arrobj2.find(arr2 => arr2.assignId === arr1.id)
)
// or
const result = arrobj1.filter(arr1 => {
return arrobj2.find(arr2 => arr2.assignId === arr1.id)
})
We can combine Array.filter() and Array.some() to make it more simple
let result = arrobj1.filter(a1 => arrobj2.some(a2 => a2.assignId === a1.id) )
console.log(result)
For your code,the reason is that you have missing return when invoke find
var arrobj1 =[
{id: 1, name: 'xxx', value:100},
{id: 2, name: 'yyy', value:200},
{id: 3, name: 'zzz', value:400}
]
var arrobj2 =[
{country: 'IN', name: 'lina', assignId:2},
{country: 'MY', name: 'john', assignId:3},
{country: 'SG', name: 'peter', assignId:6}
]
let result = arrobj1.filter(a1 => arrobj2.some(a2 => a2.assignId === a1.id) )
console.log(result)
You can generally go with the filter and some combination as #flyingfox mentioned in the answer, But if you'd have thousands of records then your time complexity would increase which you can solve by removing the nested some loop.
So more performant code would look like the following for a bigger data set.
And yes, Either use return with braces or simply remove the braces for one-liner returns!
var arrobj1 = [
{ id: 1, name: 'xxx', value: 100 },
{ id: 2, name: 'yyy', value: 200 },
{ id: 3, name: 'zzz', value: 400 },
]
var arrobj2 = [
{ country: 'IN', name: 'lina', assignId: 2 },
{ country: 'MY', name: 'john', assignId: 3 },
{ country: 'SG', name: 'peter', assignId: 6 },
]
var obj = {}
for (const elem of arrobj2) {
obj[elem.assignId] = true
}
let result = arrobj1.filter((a1) => obj[a1.id])
console.log(result)

Convert array of objects to another array of objects

I need to convert array of objects to just objects to use it in table datasource:
{v_report_full: Array(25)}
v_report_full: Array(25)
0:
first_name: "Blake"
last_name: "Thorphan"
middle_name: "Agder"
monh: "2021-02-01 00:00:00"
n_vh: "Delay 00:04:52"
n_vh_s_obeda: "ok"
n_vyh: "ok"
n_vyh_s_obeda: "ok"
name: "oitib"
rtime: null
vh_s_obeda_ts: null
vhod_ts: "2021-02-01 08:59:52"
vyh_s_obeda_ts: null
vyhod_ts: null
__typename: "Ereport"
__proto__: Object
1:.. the same next index
2:.. the same next index
Table datasource requires next order:
const dataSource = [
{
key: '1',
name: 'Mike',
age: 32,
address: '10 Downing Street',
},
{
key: '2',
name: 'John',
age: 42,
address: '10 Downing Street',
},
];
I've tried to use Object.keys, but have not enough expirience to do that. If here is a simple solution, if not I have to write a loop for each row with function to concat, etc?
Upd. These one was I worked with:
let dataSource = (data) ? data.v_report_full.map((value, index, array) => {
return {
id: value.id,
key: value.id,
first_name:(value, 'first_name'),
.....
}
After hatfield advise, I checked once more and it's working! A liitle changes and above code then working now D: What a noob I am.

How to get the list of occurence in list of object reactjs

I'm having trouble with arrays of object in React.js. I have a list of objects like this :
const list = [
{ name: name1,
age: age1,
address: addresse1
},
{ name: name2,
age: age2,
address: addresse2
},
{ name: name1,
age: age1,
address: addresse4
},
{ name: name3,
age: age3,
address: addresse3
}]
How can I get an array with every different names like that ?
['name1','name2','name3']
I tried by mapping the list and set a bool but I can't figure how to loop and compare list[i] and list[i+1] in mapping function
You can map array to make an array of names and after that leave only unique values
const list = [
{ name: 'name1',
age: 'age1',
address: 'addresse1'
},
{ name: 'name2',
age: 'age2',
address: 'addresse2'
},
{ name: 'name1',
age: 'age1',
address: 'addresse4'
},
{ name: 'name3',
age: 'age3',
address: 'addresse3',
}]
const result = [...new Set(list.map(item => item.name))]
console.log({ result })

How to edit object array?

I want to edit JavaScript object.
I have an JavaScript object like this
data_without_id = [
0: {id: 1, name: "Mary", age: null}
1: {id: 2, name: "Bob", age: 33}
2: {id: 1, name: "Kelly", age: 40}
]
I want to convert this object into this
data_without_id = [
0: {id: 1, name: "Kelly", age: 40}
1: {id: 2, name: "Bob", age: 33}
]
What I need to do is:
Group by id
Get latest value.
I tried using Array.prototype.reduce(), but I can't get the result I need...
Using the function reduce would be as follow:
The function reduce for grouping and the function Object.values for extracting the values.
let data_without_id = [ { id: 1, name: "Mary", age: null }, { id: 2, name: "Bob", age: 33 }, { id: 1, name: "Kelly", age: 40 }],
result = Object.values(data_without_id.reduce((a, {id, name, age}) => {
a[id] = {id, name, age};
return a;
}, Object.create(null)));
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could use .reduce by making the accumulator an object that has keys of the id. This way you can overwrite any previously seen objects which had the same id, and then use Object.values to get your array of objects:
const data_without_id = [{id: 1, name: "Mary", age: null}, {id: 2, name: "Bob", age: 33}, {id: 1, name: "Kelly", age: 40}],
res = Object.values(data_without_id.reduce((acc, obj) =>
(acc[obj.id] = obj, acc)
, {}));
console.log(res);
You could just simply use a for/of loop to create a copy of the data where the last object with a particular id will always be the object returned in the output data. This avoids the "grouping" part of the code but still returns the correct data.
const data_without_id = [
{ id: 1, name: "Mary", age: null },
{ id: 2, name: "Bob", age: 33 },
{ id: 1, name: "Kelly", age: 40 }
];
function lastId(arr) {
const out = [];
for (let obj of arr) {
// If you don't create a copy of each object the returned
// data will simply be contain _references_ to the original
// data. Changes in the original data will be reflected
// in the returned data
out[obj.id - 1] = { ...obj };
}
return out;
}
const lastIds = lastId(data_without_id);
console.log(lastIds);

How can I optimally group a list of objects by their sub object?

I'm trying to group some JavasScript objects by their shared similar object. I can do this effortlessly in Ruby, but for the life of my I (somewhat embarrassingly) can't figure this out in JS in linear time. JS doesn't seem to allow object literals as keys, at least for the purposes of reducing.
I have data shaped like this, as a result from a GraphQL query:
[
{
id: 1,
name: 'Bob',
room: {
id: 5,
name: 'Kitchen'
}
},
{
id: 3,
name: 'Sheila',
room: {
id: 5,
name: 'Kitchen'
}
},
{
id: 2,
name: 'Tom',
room: {
id: 3,
name: 'Bathroom'
}
}
]
In the UI, we're going to display the objects by the room they're in. We need to keep a reference to the room itself, otherwise we'd just sort by a room property.
What I'm trying to do is reshape the data into something like this:
{
{id: 5, name: 'Kitchen'}: [{id: 1, name: 'Bob'}, {id: 3, name: 'Sheila'}],
{id: 3, name: 'Bathroom'}: [{id: 2, name: 'Tom'}]
}
As you can see, the people are grouped together by the room they're in.
It could also be shaped like this...
[
{ room: {id: 5, name: 'Kitchen'}, people: [{id: 1, name: 'Bob', ...}] },
{ room: {id: 3, name: 'Bathroom', people: [{id: 2, name: 'Tom'}]
]
However it comes out, we just need the people grouped by the rooms in linear time.
I've tried lodash's groupBy, using both map and reduce, just doing for loops that put the list together, etc. I'm stumped because without being able to use an object literal (the room) as a hash index, I don't know how to efficiently group the outer objects by the inner objects.
Any help is greatly appreciated.
Update: adding clarity about trying to do it with linear time complexity - the most efficient equivalent of this Ruby code:
h = Hash.new { |h, k| h[k] = [] }
value.each_with_object(h) { |v, m| m[v[:room]] << v }
You can solve this using lodash#groupBy and lodash#map to gather and transform each group. Additionally, we use lodash#omit to remove the room object from each person from the people array.
var result = _(data)
.groupBy('room.id')
.map(people => ({
room: { ...people[0].room },
people: _.map(people, person => _.omit(person, 'room'))
})).value();
var data = [
{
id: 1,
name: 'Bob',
room: {
id: 5,
name: 'Kitchen'
}
},
{
id: 3,
name: 'Sheila',
room: {
id: 5,
name: 'Kitchen'
}
},
{
id: 2,
name: 'Tom',
room: {
id: 3,
name: 'Bathroom'
}
}
];
var result = _(data)
.groupBy('room.id')
.map(people => ({
// make sure to create a new room object reference
// to avoid mutability
room: { ...people[0].room },
people: _.map(people, person => _.omit(person, 'room'))
})).value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
You can use reduce to create an object of people indexed by rooms and then get that object's values, no library needed:
const input=[{id:1,name:'Bob',room:{id:5,name:'Kitchen'}},{id:3,name:'Sheila',room:{id:5,name:'Kitchen'}},{id:2,name:'Tom',room:{id:3,name:'Bathroom'}}]
const output = Object.values(
input.reduce((a, { id, name, room }) => {
const roomName = room.name;
if (!a[roomName]) a[roomName] = { room, people: [] };
a[roomName].people.push({ id, name });
return a;
}, {})
);
console.log(output);
Objects like
{id: 5, name: 'Kitchen'}: [{id: 1, name: 'Bob'}, {id: 3, name: 'Sheila'}],
in your question can't be properties like that unless the structure is a Map. Ordinary Javascript objects can only have string (/ number) properties.
One alternative is to use reduce in order to groupBy the rooms.
const input = [{
id: 1,
name: 'Bob',
room: {
id: 5,
name: 'Kitchen'
}
},
{
id: 3,
name: 'Sheila',
room: {
id: 5,
name: 'Kitchen'
}
},
{
id: 2,
name: 'Tom',
room: {
id: 3,
name: 'Bathroom'
}
}
];
const res = input
.map(person => ({
person: {
id: person.id,
name: person.name
},
room: person.room
}))
.reduce((rooms, person) => {
const room = rooms.find(room => room.id === person.room.id) ||
{ room: person.room };
const idx = rooms.indexOf(room);
room.people = room.people ?
[...room.people, person.person] :
[person.person];
return Object.assign(rooms, {
[idx === -1 ? rooms.length : idx]: room
});
}, []);
console.log(res);

Categories

Resources