Get index of Object inside Array and use it in a function - javascript

In Javascript, is it possible to get the Index of the object (in an array of objects) and use it inside of the same object in a function?
For example:
const foo = [
{
id: 1,
comments: getComments(this.index) // index of the object goes here
},
{
id: 34,
comments: getComments(this.index) // index of the object goes here
},
{
id: 21,
comments: getComments(this.index) // index of the object goes here
}
]
const getComments = function(index) {
return foo[index].id // return the ID of the actual object
}
Or is there a workaround for what I'm trying to achieve here?

Do it in two steps. First create the array of objects, then fill in the comments property by calling the function on each element.
const foo = [
{
id: 1,
},
{
id: 34,
},
{
id: 21,
}
]
foo.forEach(el => el.comments = getComments(el));
function getComments(obj) {
return obj.id;
}
console.log(foo);

I assume this is for learning purposes as probably the use you are thinking could be implemented in a better way. The closest that you can do is this:
let foo = [
{
id: 1,
},
{
id: 34,
},
{
id: 21,
}
]
foo = foo.map(
(elem, index) => ({...elem, comments: getComments(index)})
)
function getComments(index) {
return foo[index].id // return the ID of the actual object
}
console.log(foo[2].comments)

Related

How to dedupe an array of objects by a key value pair?

// This is a large array of objects, e.g.:
let totalArray = [
{"id":"rec01dTDP9T4ZtHL4","fields":
{"user_id":170180717,"user_name":"abcdefg","event_id":516575,
}]
let uniqueArray = [];
let dupeArray = [];
let itemIndex = 0
totalArray.forEach(x => {
if(!uniqueArray.some(y => JSON.stringify(y) === JSON.stringify(x))){
uniqueArray.push(x)
} else(dupeArray.push(x))
})
node.warn(totalArray);
node.warn(uniqueArray);
node.warn(dupeArray);
return msg;
I need my code to identify duplicates in the array by a key value of user_id within the objects in the array. Right now, my code works to identify identical objects in the array, but I need it to identify dupes based on a key value inside the objects instead. How do I do this? I am struggling to figure out how to path the for each loop to identify the dupe based on the key value instead of the entire object.
Right now, my code works to identify identical objects in the array, but I need it to identify dupes based on a key value inside the objects instead. How do I do this?
Don’t compare the JSON representation of the whole objects then, but only their user_id property specifically.
totalArray.forEach(x => {
if(!uniqueArray.some(y => y.fields.user_id === x.fields.user_id)){
uniqueArray.push(x)
} else(dupeArray.push(x))
})
You could take a Set and push to either uniques or duplicates.
var array = [
{ id: 1, data: 0 },
{ id: 2, data: 1 },
{ id: 2, data: 2 },
{ id: 3, data: 3 },
{ id: 3, data: 4 },
{ id: 3, data: 5 },
],
uniques = [],
duplicates = [];
array.forEach(
(s => o => s.has(o.id) ? duplicates.push(o) : (s.add(o.id), uniques.push(o)))
(new Set)
);
console.log(uniques);
console.log(duplicates);
.as-console-wrapper { max-height: 100% !important; top: 0; }
One way is to keep a list of ids you found so far and act accordingly:
totalArray = [
{ id: 1, val: 10 },
{ id: 2, val: 20 },
{ id: 3, val: 30 },
{ id: 2, val: 15 },
{ id: 1, val: 50 }
]
const uniqueArray = []
const dupeArray = []
const ids = {}
totalArray.forEach( x => {
if (ids[x.id]) {
dupeArray.push(x)
} else {
uniqueArray.push(x)
ids[x.id] = true
}
})
for (const obj of uniqueArray) console.log("unique:",JSON.stringify(obj))
for (const obj of dupeArray) console.log("dupes: ",JSON.stringify(obj))

Looping through (possibly infinitely) repeating object structure

I have a problem I can't get my head around. If I am looking for an object with a certain ID in a possibly infinite data structure, how can I loop through it until I find the object I need and return that object?
If this is what my data looks like, how can I get the object with id === 3 ?
{
id: 0,
categories: [
{
id: 1,
categories: [
{
id: 2,
categories: [ ... ]
},
{
id: 3,
categories: [ ... ]
},
{
id: 4,
categories: [ ... ]
},
]
}
]
}
I tried the following:
findCategory = (categoryID, notesCategory) => {
if (notesCategory.id === categoryID) {
return notesCategory;
}
for (let i = 0; i < notesCategory.categories.length; i += 1) {
return findCategory(categoryID, notesCategory.categories[i]);
}
return null;
};
But that doesn't get ever get to id === 3. It checks the object with id: 2 and then returns null. It never gets to the object with id: 3.
Here is a JSbin: https://jsbin.com/roloqedeya/1/edit?js,console
Here is the case. when you go in to the first iteration of 'for' loop, because of the return call, the execution is go out from the function. you can check it by using an console.log to print the current object in the begin of your function.
try this
function find(obj, id) {
if(obj.id === id) {
console.log(obj) // just for testing. you can remove this line
return obj
} else {
for(var i = 0; i < obj.categories.length; i++) {
var res = find(obj.categories[i], id);
if(res) return res;
}
}
}
hope this will help you. thanks
You need to store the intermediate result and return only of the object is found.
function findCategory(object, id) {
var temp;
if (object.id === id) {
return object;
}
object.categories.some(o => temp = findCategory(o, id));
return temp;
}
var data = { id: 0, categories: [{ id: 1, categories: [{ id: 2, categories: [] }, { id: 3, categories: [] }, { id: 4, categories: [] }] }] }
result = findCategory(data, 3);
console.log(result);

Create object with new key and assign same array

Do you have an optimised solution for the following.
let say,
x = { users: [ {id: 1}, {id:2}, {id:3} ] }
I want to make a new key with same values, the output should be,
{ users: { list: [ {id: 1}, {id:2}, {id:3} ], count: 3 }
Using only JS or Underscore with one line code w/o any extra effort.
I know other tricks to do the same, but do we have one line solution for the same ?
Help appreciated...
Thanks.
Create the object, and assign the x array to list. However, count should be a getter, since the list length might change:
const x = { users: [{ id: 1 }, { id: 2 }, { id: 3 }] };
const result = {
users: {
list: x.users,
get count() { return this.list.length; }
}
};
console.log(JSON.stringify(result));
result.users.list.push({ id: 4 });
console.log(JSON.stringify(result));
I'm not sure why this is to be an optimised solution because this is a simple plain-JavaScript problem:
let x = { users: [{ id: 1 }, { id: 2 }, { id: 3 }] };
let result = {
users: {
list: x.users,
count: x.users.length
}
};
console.log(result);
Sure, just define the property as an object
const obj = {
users: [{
id: 1
}, {
id: 2
}, {
id: 3
}]
};
obj.users = { list: obj.users, count: obj.users.length };
console.log(obj);
I recommend focusing on code clarity rather than on line conservation though

What is the best way to convert an array of strings into an array of objects in Angular 2?

Let's say I have an array as follows:
types = ['Old', 'New', 'Template'];
I need to convert it into an array of objects that looks like this:
[
{
id: 1,
name: 'Old'
},
{
id: 2,
name: 'New'
},
{
id: 3,
name: 'Template'
}
]
You can use map to iterate over the original array and create new objects.
let types = ['Old', 'New', 'Template'];
let objects = types.map((value, index) => {
return {
id: index + 1,
name: value
};
})
You can check a working example here.
The solution of above problem is the map() method of JavaScript or Type Script.
map() method creates a new array with the results of calling
a provided function on every element in the calling array.
let newArray = arr.map((currentvalue,index,array)=>{
return Element of array
});
/*map() method creates a new array with the results of calling
a provided function on every element in the calling array.*/
let types = [
'Old',
'New',
'Template'
];
/*
let newArray = arr.map((currentvalue,index,array)=>{
return Element of array
});
*/
let Obj = types.map((value, i) => {
let data = {
id: i + 1,
name: value
};
return data;
});
console.log("Obj", Obj);
Please follow following links:
TypeScript
JS-Fiddle
We can achieve the solution of above problem by for loop :
let types = [
"One",
"Two",
"Three"
];
let arr = [];
for (let i = 0; i < types.length; i++){
let data = {
id: i + 1,
name: types[i]
};
arr.push(data);
}
console.log("data", arr);

How can I concat an array to an array that is inside an array of objects?

I am trying to concat an array to an array (productsCategories) inside an array of objects.
So, here's what the productCategories array looks like:
[
{
id: 123,
items: [ { Obj1 }, { Obj2 } ]
},
{
id:456,
items: [ { Obj1 }, { Obj2 } ]
}
]
I have some new array, like [ { Obj3 }, { Obj4 } ] that I want to concat to the productCategories for the object where id = 123.
So to do this,
I've first used lodash's find to find the correct object to update and used concat to join the two arrays:
let nextItems:any = find(productCategories, { id: payload.id });
nextItems = assign({}, nextItems, { items: nextItems.items.concat(payload.items)});
So, nextItems.items has the concatenated items array.
However, I am having trouble now adding this to productCategories array. I need to find the object where id is the same as nextItems.id and then set productCategories.items equal to nextItems.items.
What is the correct way to do this?
Find the index of the object that matches the nextItems.id in the productCategories and assign the new concatenated array to it. You can use the lodash findIndex() method to find the index of the object that matches the id.
var index = _findIndex(productCategories, { id: nextItems.id });
productCategories[index].items = nextItems.items;
You can use plain JavaScript just as well. With ES6 spread syntax it can look like this:
productCategories.filter(x => x.id == payload.id)
.forEach(x => x.items.push(...payload.items));
Here is a snippet with sample data:
// Sample data
var productCategories = [{
id: 123,
items: [ { a: 1 }, { a: 2 } ]
}, {
id: 456,
items: [ { b: 1 }, { b: 2 } ]
}];
var payload = {
id: 123,
items: [ { c: 1 }, { c: 2 } ]
};
// Update with payload
productCategories.filter(x => x.id == payload.id)
.forEach(x => x.items.push(...payload.items));
// Show results
console.log(productCategories);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Categories