Replace array of objects with new object [closed] - javascript

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 last year.
Improve this question
I have an array of objects and I would like to replace an object with a new object that has a specific id. My goal is to replace/remove the object where id === 'hotel' with an entirely new object and keep the same index.
Example / Current Code
const sampleArray = [{ id: 'price' }, { id: 'hotel1', filters: [] }, { id: 'type' }]
const index = sampleArray.findIndex((obj) => obj.id === 'hotel1') // find index
sampleArray = sampleArray.splice(index, 0) // remove object at this index
sampleArray.splice(index, 0, { id: 'hotel2' }) // attempt to replace with new object ... not working :(

You don't need the fancy splice logic. Just set the array element and forget it.
const sampleArray = [{ id: 'price' }, { id: 'hotel1', filters: [] }, { id: 'type' }]
const index = sampleArray.findIndex((obj) => obj.id === 'hotel1'); // find index
sampleArray[index] = { id: 'hotel2' }; // replace with new object ... working :)
console.log(JSON.stringify(sampleArray));

You can use the map() function:
const updatedArray = sampleArray.map(item => item.id === 'hotel' ? {...item, id: 'hotel2'} : item);

Another way, replacing an array element by index
const sampleArray = [{ id: 'price' }, { id: 'hotel1', filters: [] }, { id: 'type' }]
const index = sampleArray.findIndex((obj) => obj.id === 'hotel1'); // find index
Object.assign(sampleArray, { [index]: { id: 'hotel2' } }); // replace with new object
console.log(sampleArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Related

Format object with some keys to array [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 11 months ago.
Improve this question
It gets a specific result from my database which I have shown below:
const data = {
short: 'en',
element: {
'dsdsea-22dada-2ffgd-xxada-eeee': { name: 'test name', comment: 'test comment' },
'adad2a-dda13-dsdad-wwwwd-adaxx': { name: 'name 2' },
}
And I would like to apply a JavaScript operation to be able to get this result:
[
{
short: 'en',
key: "dsdsea-22dada-2ffgd-xxada-eeee.name"
value: "test name"
},
{
short: 'en',
key: "dsdsea-22dada-2ffgd-xxada-eeee.comment"
value: "test comment"
},
{
short: 'en',
key: "adad2a-dda13-dsdad-wwwwd-adaxx.name"
value: "name 2"
}
]
I have tried using a combination of Object.entries and the map function, but I don't know how to deal with double keys in a single element object.
This may be one possible solution to achieve the desired objective.
It uses Object.entries(), .map(), .flatMap() and template literal using backtick `` characters.
Code Snippet
const getTransformedArray = obj => (
Object.entries(obj.element) // iterate over 'element' key-value pairs
.flatMap(([k1, v1]) => ( // k1-v1 where v1 is object (with name, comment props)
Object.entries(v1) // iterate over v1's key-value pairs
.map(([k2, v2]) => ({ // map each iteration
short: obj.short, // create the resulting object
key: `${k1}.${k2}`, // 'key' is created using k1, k2
value: v2 // 'value' is v2 as-is
}))
)) // '.flatMap' used above avoids nesting of arrays
);
const data = {
short: 'en',
element: {
'dsdsea-22dada-2ffgd-xxada-eeee': { name: 'test name', comment: 'test comment' },
'adad2a-dda13-dsdad-wwwwd-adaxx': { name: 'name 2' }
}
};
console.log(getTransformedArray(data));
Explanation
Inline comments in the code-snippet above explain how the code works.
EDIT
Answer updated to use .flatMap() as has been highlighted by #pilchard.
You'll need two loops to iterate over each element and then each value of those elements.
Here using for...of loops on the Object.entries() of each, destructuring at each level to apply relevant names to each property, and then creating a compound key value using a template literal
const data = {
short: 'en',
element: {
'dsdsea-22dada-2ffgd-xxada-eeee': { name: 'test name', comment: 'test comment' },
'adad2a-dda13-dsdad-wwwwd-adaxx': { name: 'name 2' },
}
}
const result = [];
for (const [key, element] of Object.entries(data.element)) {
for (const [prop, value] of Object.entries(element)) {
result.push({ short: data.short, key: `${key}.${prop}`, value })
}
}
console.log(result)
You can do:
const data = {short: 'en',element: {'dsdsea-22dada-2ffgd-xxada-eeee': {name: 'test name',comment: 'test comment'},'adad2a-dda13-dsdad-wwwwd-adaxx': {name: 'name 2'}}}
const result = Object
.entries(data.element)
.reduce((a, [key, obj]) => [
...a,
...Object
.values(obj)
.map(value => ({
...{
short: data.short,
key
},
value
}))
], [])
console.log(result)
Use Object.keys() to get the keys in element, then map the returned array using the key to access each element object and thus getting the name.
Here's the full code snippet:
const input = {
short: 'en',
element: {
'dsdsea-22dada-2ffgd-xxada-eeee': { name: 'test name', comment: 'test comment' },
'adad2a-dda13-dsdad-wwwwd-adaxx': { name: 'name 2' },
},
};
function format(data = {}) {
const { short = '', element = {} } = data;
let result = Object.keys(element).map((key) => {
return Object.values(element[key]).map((value) => ({ short, key, value }));
});
result = result.flat();
return result;
}
const result = format(input);
console.log(result)
this prints:
[
{
"short": "en",
"key": "dsdsea-22dada-2ffgd-xxada-eeee",
"value": "test name"
},
{
"short": "en",
"key": "dsdsea-22dada-2ffgd-xxada-eeee",
"value": "test comment"
},
{
"short": "en",
"key": "adad2a-dda13-dsdad-wwwwd-adaxx",
"value": "name 2"
}
]

Create object with a function or a function that takes an object? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed last year.
Improve this question
In my project, I have to work with a list of complex objects, even nested ones.
For this question, I will replace that with a basic object: {value: number}
I have an array of that object, and now I would like to go over the array and check the object's value:
// First way: Using one function:
console.log("Way #1")
// So I have an array like this:
itemArr = [{
value: 1
}, {
value: 2
}, {
value: 3
}, {
value: 1
}]
// The function is implemented outside of the objects:
const check = (item) => {
switch (item.value) {
case 1:
return "is one"
case 2:
return "is two"
case 3:
return "is three"
}
}
itemArr.forEach((item) => {
console.log(check(item))
})
// Second way
// The function is implemented inside of the object.
console.log("Way #2")
itemArr = [{
value: 1,
check: () => "is one"
}, {
value: 2,
check: () => "is two"
}, {
value: 3,
check: () => "is three"
}, {
value: 1,
check: () => "is one" // this way, even if a value is repeated, I have to write the function again.
}]
itemArr.forEach((item) => {
console.log(item.check())
})
Is there an obviously better choice in general?
Which way is more efficient / has better performance?
The first way is better. The Second way creates a function in memory for every object of the array.
Reference for better memory management
But in the real time try to find some generic way so that the things can be done in a loop.
none of them.
it seems absurd to me because it derogates from the maintainability rules of the code: the informational data must not be mixed in the algorithmic part
do that ?
const itemArr =
[ { value: 1 }
, { value: 2 }
, { value: 3 }
, { value: 1 }
]
const check = []
check[3] = 'is three'
check[1] = 'is one'
check[2] = 'is two'
// or : const check = [,'is one','is two','is three' ]
itemArr.forEach(({value: x}) => console.log(check[x]))
if you absolutely want to use a function...
const itemArr =
[ { value: 1 }
, { value: 2 }
, { value: 3 }
, { value: 1 }
]
const checkItem = (()=>
{
const msg = []
msg[3] = 'is three' // in any order you want
msg[1] = 'is one'
msg[2] = 'is two'
return (val) => msg[val]
})()
itemArr.forEach(({value: x}) => console.log(checkItem(x)))

Check if Object has keys [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have a Object in this format.
const obj = [{
name: 'name',
items: [{
name: 'name 1',
items: [
{ value: 100 },
{ value: 50 }
]
}]
}]
Imagine that all arrays repeat several times in length and an object inside another.
How I can iterate all objects in all arrays and check if all have the property "name" and "items", if it doesn't have check if has the property "value".
I trying to make a recursion but I don't no how to check if the last "items" has a value to stop and continue to check the rest.
Thanks everyone.
You can use Object.prototype.hasOwnProperty to check if an object has a specific property and Array.prototype.flatMap to map the inner arrays to a single array.
const obj = [{
name: 'name',
items: [{
name: 'name 1',
items: [
{ value: 100 },
{ value: 50 },
{
name: 'name 2',
items: [{
value: 150
}]
}
]
}]
}];
function getValues(arr) {
return arr.flatMap(entry => {
if (entry.hasOwnProperty('name') && entry.hasOwnProperty('items')) {
return getValues(entry.items);
}
return entry.value;
});
}
console.log(getValues(obj));
I resolve my question with:
function check(objs) {
for (let obj of objs) {
if(!('name' in obj) &&
!('value' in obj))
throw new Error('invalid')
if('name' in obj)
check(obj.items)
}
}

Counting object in side array of array object by property javascript [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have data like:
var data = [
{
items: [
{
id: 123
},
{
id: 234
},
{
id: 123
}
]
}, {
items: [
{
id: 123
},
{
id: 234
}
]
}
]
so, I want count object deep in array inside of all data by property 'id'.
ex: data.countObject('id',123) //return 3.
and my data have about xx.000 item, which solution best?
Thanks for help (sorry for my English)
You can use reduce & forEach. Inside the reduce callback you can access the items array using curr.items where acc & curr are just parameters of the call back function. Then you can use curr.items.forEach to get each object inside items array
var data = [{
items: [{
id: 123
},
{
id: 234
},
{
id: 123
}
]
}, {
items: [{
id: 123
},
{
id: 234
}
]
}];
function getCount(id) {
return data.reduce(function(acc, curr) {
// iterate through item array and check if the id is same as
// required id. If same then add 1 to the accumulator
curr.items.forEach(function(item) {
item.id === id ? acc += 1 : acc += 0;
})
return acc;
}, 0) // 0 is the accumulator, initial value is 0
}
console.log(getCount(123))

Remove specific element from array of specifc object [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I need to modify a nested array. In this example I would like to remove content 2 from the target array of the object with the id ZFrNsQKSY6ywSzYps
var array = [
{ _id: "QKSY6ywSzYpsZFrNs", target: ["content 1"]}
{ _id: "ZFrNsQKSY6ywSzYps", target: ["content 1", "content 2"]}
{ _id: "SzYpsZFrNQKSY6yws", target: ["content 1"]}
]
I tried to use find() but with that I do not update the array. So this seems not to be the correct approach.
You can use find() method to get object and then indexOf() to find element in array that you want to remove and if found splice() method to remove it.
var array = [
{ _id: "QKSY6ywSzYpsZFrNs", target: ["content 1"]},
{ _id: "ZFrNsQKSY6ywSzYps", target: ["content 1", "content 2"]},
{ _id: "SzYpsZFrNQKSY6yws", target: ["content 1"]}
]
const obj = array.find(({_id}) => _id == 'ZFrNsQKSY6ywSzYps');
if(obj) {
const i = obj.target.indexOf('content 2');
if(i != -1) obj.target.splice(i, 1)
}
console.log(array)
var newarray = []
for(var i1 = 0; i1< array.length;i1++){
var subarray = []
for(var i2 = 0; i1<array[0].target.length;i++){
if(array[0].target[0]!="content 2"){ // or desired removed content
subarray.push(array[0].target[0])
}
}
newarray.push({"_id":array[0].id,"target":subarray})
}
after that simply access newarray
First: elements in array should be separated by commas.
Second: Is there some logic to update target arrays? If so you can iterate over the elements and modify their targets according to that logic.
Other than that you can always do this
array[1].target = ["content1"]
Try tihs approach:
const array = [
{ _id: "QKSY6ywSzYpsZFrNs", target: ["content 1"]},
{ _id: "ZFrNsQKSY6ywSzYps", target: ["content 1", "content 2"]},
{ _id: "SzYpsZFrNQKSY6yws", target: ["content 1"]}
]
console.log(array);
array.forEach(
item =>
// filter out the unwanted content
item.target = item.target.filter(
content => content !== "content 2"
)
)
console.log(array);

Categories