Exclude given objects from array - javascript

I have the below array. I am attempting to exclude certain objects from this array in processing.
For example. I would like to exclude the type 'dog' and only use any object that is of type duck.
I'd like to do this using underscore/lodash but will use plain JS if need be.
animals: [
{
type: 'duck',
name: 'quack',
},
{
type: 'duck',
name: 'quieck',
},
{
type: 'dog',
name: 'bark',
},
]

The Underscore/LoDash way, would be just
var result = _.where(animals, {type: 'duck'});

I suppose your array represents variable animals. You can use Array.prototype.filter() function. If you want all ducks:
const animals = [
{ type: 'duck', name: 'quack' },
{ type: 'duck', name: 'quieck' },
{ type: 'dog', name: 'bark' },
];
const ducks = animals.filter(o => o.type === 'duck');
or if you want to exclude all dogs:
const withoutDogs = animals.filter(o => o.type !== 'dog');
I used ES6 syntax. ES5 equivalent would be:
var ducks = animals.filter(function(o) { return o.type === 'duck' });

Related

Return all values of nested arrays using string identifier

Given an object searchable, is there a simple way of returning all the id values using lodash or underscore.js (or equivalent) where I can define the path to id?
const searchable = {
things: [
{
id: 'thing-id-one',
properties: [
{ id: 'd1-i1' },
{ id: 'd1-i2' },
]
},
{
id: 'thing-id-two',
properties: [
{ id: 'd2-i1' },
{ id: 'd2-i2' },
]
}
]
}
I am looking to see if this is possible in a manner similar to how we can use lodash.get e.g. if we wanted to return the things array from searchable we could do
const things = _.get(searchable, 'things');
I can't seem to find anything similar in the documentation. I am looking for something
that could contain an implementation similar to:
_.<some_function>(searchable, 'things[].properties[].id')
Note: I am well aware of functions like Array.map etc and there are numerous ways of extracting the id property - it is this specific use case that I am trying to figure out, what library could support passing a path as a string like above or does lodash/underscore support such a method.
Found a solution using the package jsonpath
const jp = require('jsonpath');
const result = jp.query(searchable, '$.things[*].properties[*].id')
console.log(result);
// outputs: [ 'd1-i1', 'd1-i2', 'd2-i1', 'd2-i2' ]
you can do it easily in plain js
like this
const searchable = {
things: [
{
id: 'thing-id-one',
properties: [
{ id: 'd1-i1' },
{ id: 'd1-i2' },
]
},
{
id: 'thing-id-two',
properties: [
{ id: 'd2-i1' },
{ id: 'd2-i2' },
]
}
]
}
const search = (data, k) => {
if(typeof data !== 'object'){
return []
}
return Object.entries(data).flatMap(([key, value]) => key === k ? [value]: search(value, k))
}
console.log(search(searchable, 'id'))
_.map and _.flatten together with iteratee shorthands let you expand nested properties. Every time you need to expand into an array, just chain another map and flatten:
const searchable = {
things: [
{
id: 'thing-id-one',
properties: [
{ id: 'd1-i1' },
{ id: 'd1-i2' },
]
},
{
id: 'thing-id-two',
properties: [
{ id: 'd2-i1' },
{ id: 'd2-i2' },
]
}
]
}
// Let's say the path is "things[].properties[].id"
const result = _.chain(searchable)
.get('things').map('properties').flatten()
.map('id').value();
console.log(result);
<script src="https://cdn.jsdelivr.net/npm/underscore#1.13.4/underscore-umd-min.js"></script>

Replace all values in an object with a specific key

My goal here is to convert all type values in the array below to the types in the object that collerate to numbers.
let obj = [
{
type: 'boolean',
name: 'coolName',
description: 'First description',
required: false
},
{
type: 'subcommand',
name: 'destroy',
description: 'Destroy something',
options: [
{
type:"integer",
name:"amount",
description:"How much would you like to destroy?",
required: true
}
]
}
]
const types = {
'subcommand':1,
'subcommandgroup':2,
'string':3,
'integer':4,
'boolean':5,
'user':6,
'channel':7,
'role':8,
'mentionable':9,
'number':10,
'attachment':11
}
I've been looking for a while and cannot find a function that also iterates through the nested object, if anyone has a way to do this please let me know.
obj.map(o => {
o.type = types[o.type]
if(o.options){
o.options.map(opt => {
opt.type = types[opt.type]
})
}
return o;
})

Filter an array of objects with a second array with multiple values

I am trying to write a function to take the first object in the "parent" array, pull out the child field (which is in that array) and use that field to filter the second object called "child".
I want to get all the related records from the child object that are in the child field in the parent object.
Expected output
child: [
{
**id: 1,**
name: 'Jimmy Yukka',
},
{
**id: 2,**
name: 'Up North',
}
INPUT
Parent: [
{
**id: 1,**
name: 'Melbourne Bands',
**child: [1, 2]**
}
I have the following data
Parent: [
{
**id: 1,**
name: 'Melbourne Bands',
**child: [1, 2]**
},
{
id: 2,
name: 'Sydney Bands',
child: [3]
}
],
child: [
{
**id: 1,**
name: 'Jimmy Yukka',
},
{
**id: 2,**
name: 'Up North',
},
{
id: 3,
url: 'jimmyyukka.com',
name: 'INXS',
CreatedByUserId: 1
}
],
The code of the function I have implemented so far:
currentChildrenIds(ParentId, parentData, childData) {
const singleParentRecord = parentData.filter(function(parent) {
return parent.id === ParentId;
});
const parentsChildIds = singleParentRecord[0].books;
const childRecords = childData.filter(function(child) {
return child.id === parentsChildIds
});
return childRecords
}
NOTES
This bit here is where it is wrong
const childRecords = childData.filter(function(child) {
return child.id === parentsChildIds
This bit here is also a bit rubbish (hardcoding the [0])but not I'm not sure how I should be coding it correctly
const parentsChildIds = singleParentRecord[0].books;
here,
const childRecords = childData.filter(function(child) {
return child.id === parentsChildIds
parentsChildIds is a reference to an array: you don't want to test if an id is === to a a reference,
You have to be explicit and check if the id is contained in the array:
const childRecords = childData.filter(function(child) {
return parentsChildIds.includes(child.id)
Regarding the singleParentRecord[0] that does feel weird,
since you know the method filter will always return an array of size 1 or 0,
you can use the method find instead of filter
Also in functionnal programming (array functions such as filter, map, find...)
I advice you to read a bit about the arrow function syntax because:
The syntex is more dense and it makes it easier for your brain to understand when several functions are chained
If you want to use variables which are defined outside of the function it will be available only inside of an arrow function
your code with an arrow function:
const childRecords = childData.filter((child) => {
return child.id === parentsChildIds
}
Try this:
const Parent = [
{
id: 1,
name: 'Melbourne Bands',
child: [1, 2]
},
{
id: 2,
name: 'Sydney Bands',
child: [3]
}
];
const children = [
{
id: 1,
name: 'Jimmy Yukka',
},
{
id: 2,
name: 'Up North',
},
{
id: 3,
url: 'jimmyyukka.com',
name: 'INXS',
CreatedByUserId: 1
}
];
// We create a new array with Array.map
const result = Parent.map(parent => ({
// Spread properties of the parent
...parent,
// Override the child property and filter the children array with the `includes` method
child: children.filter(child => parent.child.includes(child.id)),
}))
console.log(result);

Comparing two parameters of an object array in JavaScript

I am completing a homework assignment where I will have to filter an array into a new array for a vehicle with the term of “ford” in it. The assignment wants the format to be in ES6 using the arrow function syntax so something like
const arr = [
{name: “Honda”, type: “Accord”},
{name: “ford”, type: “fusion”},
{name: “Toyota”, type: “Camry”}
]
const newArr = [...arr].filter(value => value === ‘ford’);
Console.log(newArr);
I know this is incorrect and wouldn’t actually get the name of the vehicle that has “ford” in it but I’m giving an example on how they would want it formatted.
You need value.name also check the quotes. In this case there may not be any use of the spread operator
const arr = [{
name: 'Honda',
type: 'Accord'
},
{
name: 'ford',
type: 'fusion'
},
{
name: 'Toyota',
type: 'Camry'
}
]
const newArr = arr.filter(value => value.name === 'ford');
console.log(newArr);

json object from javascript nested array

I'm using a nested array with the following structure:
arr[0]["id"] = "example0";
arr[0]["name"] = "name0";
arr[1]["id"] = "example1";
arr[1]["name"] = "name1";
arr[2]["id"] = "example2";
arr[2]["name"] = "name2";
now I'm trying to get a nested Json Object from this array
arr{
{
id: example0,
name: name00,
},
{
id: example1,
name: name01,
},
{
id: example2,
name: name02,
}
}
I tought it would work with JSON.stringify(arr); but it doesen't :(
I would be really happy for a solution.
Thank you!
If you are starting out with an array that looks like this, where each subarray's first element is the id and the second element is the name:
const array = [["example0", "name00"], ["example1", "name01"], ["example2", "name02"]]
You first need to map it to an array of Objects.
const arrayOfObjects = array.map((el) => ({
id: el[0],
name: el[1]
}))
Then you can call JSON.stringify(arrayOfObjects) to get the JSON.
You need to make a valid array:
arr = [
{
id: 'example0',
name: 'name00',
},
{
id: 'example1',
name: 'name01',
},
{
id: 'example2',
name: 'name02',
}
];
console.log(JSON.stringify(arr));
Note that I am assigning the array to a variable here. Also, I use [] to create an array where your original code had {}.

Categories

Resources