indexOf on array of object instead of array [duplicate] - javascript

This question already has answers here:
Get the index of the object inside an array, matching a condition
(16 answers)
Closed 5 years ago.
I know to find a value exist or not in an array I can use indexOf, but how to do it with an array of object?
const x = [{
"id": "roadshows",
"name": "Roadshows"
}, {
"id": "sporting_events",
"name": "Sporting Events"
}]
console.log( x.indexOf('roadshows') ) // don't work

Since this is tagged ecmascript-6, here's an ES6 array method: Array#findIndex():
const x = [{
"id": "roadshows",
"name": "Roadshows"
}, {
"id": "sporting_events",
"name": "Sporting Events"
}]
console.log( x.findIndex( o => o.id === 'roadshows' ) )
If you want a more re-useable way of doing this, consider creating a factory isId(id):
function isId(id) {
return (o) => o.id === id;
}
const x = [{
"id": "roadshows",
"name": "Roadshows"
}, {
"id": "sporting_events",
"name": "Sporting Events"
}]
console.log( x.findIndex( isId('roadshows') ) )
This is referred to as a "factory" because it is a function that returns a function with the passed parameter in its scope.

You have to loop through since you have object's inside array.
for(var i = 0; i < x.length; i++) {
if (x[i].id== 'roadshows') {
console.log(i);
break;
}
}
Or if you just checking that the object exist with that id, filter is handy
if (x.filter(function(e) x.id== 'roadshows').length > 0) {
// Yay. Do Something
}

manually I'd do something like this:
for(let item of x) {
if ( item.hasOwnProperty('id') && item['id'] == 'roadshows' ) {
//do your stuff here
}
}

And if you can use es6 and want to return the object in question, then there is always Array.prototype.find()
x.find( item => { return item.id === "roadshows" } )
// returns {id: "roadshows", name: "Roadshows"}

You have a couple of options.
First and foremost, findIndex. You pass it a function that tests if an element is what you are looking for, it returns the index of the first element that makes that function return true.
x.findIndex((o) => o.id === 'roadshows');
const x = [{
"id": "roadshows",
"name": "Roadshows"
}, {
"id": "sporting_events",
"name": "Sporting Events"
}];
console.log(x.findIndex((o) => o.id === 'roadshows'));
Another option is first mapping the relevant property to an array and searching in that one.
x.map((o) => o.id).indexOf('roadshows');
const x = [{
"id": "roadshows",
"name": "Roadshows"
}, {
"id": "sporting_events",
"name": "Sporting Events"
}];
console.log(x.map((o) => o.id).indexOf('roadshows'));

Related

Javascript count unique values of object property in an object array [duplicate]

This question already has answers here:
Javascript - Return only unique values in an array of objects
(6 answers)
Closed 2 years ago.
How do I calculate the unique values of an object property when I have an array of objects?
let organisations = [
{
"id": 1,
"name": "nameOne",
},
{
"id": 2,
"name": "nameTwo",
},
{
"id": 3,
"name": "nameOne",
}
]
In this case, how do I calculate the number of unique organisation names. The answer here is two, because there are two unique names.
This doesn't work
var counts = this.filteredExtendedDeals.reduce(
(organisations, name) => {
counts[name] = (counts[name] || 0) + 1;
return counts;
},
{}
);
return Object.keys(counts);
You could reduce the list into a Set and then grab the size.
const organisations = [
{ "id": 1, "name": "nameOne" },
{ "id": 2, "name": "nameTwo" },
{ "id": 3, "name": "nameOne" }
];
const uniqueItems = (list, keyFn) => list.reduce((resultSet, item) =>
resultSet.add(typeof keyFn === 'string' ? item[keyFn] : keyFn(item)),
new Set).size;
console.log(uniqueItems(organisations, 'name'));
console.log(uniqueItems(organisations, ({ name }) => name));

Convert an array of objects to a dictionary by letter [duplicate]

This question already has answers here:
Most efficient method to groupby on an array of objects
(58 answers)
Closed 3 years ago.
I have an array of objects that looks like this:
let stuff = [
{
"id": "48202847",
"name": "Doe"
},
{
"id": "17508",
"name": "Marie"
},
{
"id": "175796",
"name": "Robert"
},
{
"id": "175796",
"name": "Ronald"
},
]
What I want to get is a dictionary looking something like this:
{
"D": [{"id": "48202847", "name": "Doe"}],
"M": [{"id": "17508", "name": "Marie"}],
"R": [{"id": "175796", "name": "Robert"}, {"id": "175796", "name": "Ronald"}]
}
Notice how all the people whose name starts with "R" are listed under one key.
This is my function that creates a dictionary with the person's name as the key:
const byId = (array) =>
array.reduce((obj, item) => {
obj[item.name] = item
return obj
}, {})
But this obviously doesn't do what I want it to. I do have some ideas of how to make this possible, but they are extremely legacy and I would love to know how to do this right.
Any help is appreciated!
You need the first character, uppercase and an array for collecting the objects.
const byId = array =>
array.reduce((obj, item) => {
var key = item.name[0].toUpperCase(); // take first character, uppercase
obj[key] = obj[key] || []; // create array if not exists
obj[key].push(item); // push item
return obj
}, {});
let stuff = [{ id: "48202847", name: "Doe" }, { id: "17508", name: "Marie" }, { id: "175796", name: "Robert" }, { id: "175796", name: "Ronald" }],
result = byId(stuff)
console.log(result);
Here's a solution based on Set, map, reduce and filter:
let stuff = [{"id": "48202847","name": "Doe"},{"id": "17508","name": "Marie"},{"id": "175796","name": "Robert"},{"id": "175796","name": "Ronald"}];
let result = [...new Set(stuff.map(x => x.name[0]))]
.reduce((acc, val) => {
return acc = { ...acc,
[val]: stuff.filter(x => x.name.startsWith(val))
}
}, {});
console.log(result);
Great solution Nina! Could be made a little cleaner by utilizing the spread operator.
const byId = (array) =>
array.reduce((obj, item) => {
var key = item.name[0].toUpperCase();
return {
...obj,
[key]: obj[key] ? [...obj[key], item] : [item],
}
}, {});

Remove a particular name inside an array [duplicate]

This question already has answers here:
How can I remove a specific item from an array in JavaScript?
(142 answers)
Closed 4 years ago.
{
"list": [{
"name": "car",
"status": "Good",
"time": "2018-11-02T03:26:34.350Z"
},
{
"name": "Truck",
"status": "Ok",
"time": "2018-11-02T03:27:23.038Z"
},
{
"name": "Bike",
"status": "NEW",
"time": "2018-11-02T13:08:49.175Z"
}
]
}
How do I remove just the car info from the array.
To achieve expected result, use filter option to filter out car related values
var obj = {"list":[ {"name":"car", "status":"Good", "time":"2018-11-02T03:26:34.350Z"}, {"name":"Truck", "status":"Ok", "time":"2018-11-02T03:27:23.038Z"}, {"name":"Bike", "status":"NEW", "time":"2018-11-02T13:08:49.175Z"} ]}
let result = {
list: []
}
result.list.push(obj.list.filter(v => v.name !=='car'))
console.log(result)
codepen - https://codepen.io/nagasai/pen/MzmMQp
Option 2: without using filter as requested by OP
Use simple for loop to achieve same result
var obj = {"list":[ {"name":"car", "status":"Good", "time":"2018-11-02T03:26:34.350Z"}, {"name":"Truck", "status":"Ok", "time":"2018-11-02T03:27:23.038Z"}, {"name":"Bike", "status":"NEW", "time":"2018-11-02T13:08:49.175Z"} ]}
let result = {
list: []
}
for(let i =0; i< obj.list.length; i++){
if(obj.list[i].name !== 'car' ){
result.list.push(obj.list[i])
}
}
console.log(result)
const obj = JSON.parse(jsonString);
let yourArray = obj.list;
let filteredArray = yourArray.filter(elem => elem.name !== "car");

Removing an object from an array if it exists in the array already (Otherwise add it)

I have a set of checkboxes - which the user ticks on. The checkboxes pass some data an id and a name that i need later on for sorting. Because two objects are not equal even though they contain the same values I cant use Array.includes.
Here is an example of the data
[
{
"id": 9,
"name": "age_group_ids"
},
{
"id": 9,
"name": "age_group_ids"
},
{
"id": 9,
"name": "earnings_group_ids"
},
{
"id": 3,
"name": "earnings_group_ids"
},
]
This is the current function (which would work if the items were not objects
const submitFilterDetails = (value) => {
return async (dispatch,getState) => {
const currentArray = (getState().filter.filtersArray);
if(!currentArray.includes(value)) {
dispatch(addToFiltersArray(value))
} else {
dispatch(removeFromFiltersArray(value));
}
}
}
How can you sort this so I only have unique values
You can use find :
YourArray.find(obj => obj.id == value.id && obj.name == value.name);
const src = [
{
"id": 9,
"name": "age_group_ids"
},
{
"id": 9,
"name": "age_group_ids"
},
{
"id": 1,
"name": "earnings_group_ids"
},
]
const out = src.reduce((acc, curr) => acc.some(i => i.id === curr.id) ? acc : acc.concat([curr]) , [])
// the `out` variable has 2 unique items

searching a nested javascript object, getting an array of ancestors

I have a nested array like this:
array = [
{
"id": "67",
"sub": [
{
"id": "663",
},
{
"id": "435",
}
]
},
{
"id": "546",
"sub": [
{
"id": "23",
"sub": [
{
"id": "4",
}
]
},
{
"id": "71"
}
]
}
]
I need to find 1 nested object by its id and get all its parents, producing an array of ids.
find.array("71")
=> ["546", "71"]
find.array("4")
=> ["546", "23", "4"]
What's the cleanest way to do this? Thanks.
Recursively:
function find(array, id) {
if (typeof array != 'undefined') {
for (var i = 0; i < array.length; i++) {
if (array[i].id == id) return [id];
var a = find(array[i].sub, id);
if (a != null) {
a.unshift(array[i].id);
return a;
}
}
}
return null;
}
Usage:
var result = find(array, 4);
Demo: http://jsfiddle.net/Guffa/VBJqf/
Perhaps this - jsonselect.org.
EDIT: I've just had a play with JSONSelect and I don't think it's appropriate for your needs, as JSON does not have an intrinsic 'parent' property like xml.
It can find the object with the matching id, but you can't navigate upwards from that. E.g.
JSONSelect.match(':has(:root > .id:val("4"))', array)
returns me:
[Object { id="4"}]
which is good, it's just that I can't go anywhere from there!

Categories