lodash filter in array - javascript

in lodash there is a possibility to filter within an array which is in an object?
I have an object that has an array in it. It looks like this
{
"id": "1",
"name": "Test 1",
"tag": ["blue","red", "yellow"]
},
{
"id": "2",
"name": "Test 2",
"tag": ["red", "yellow"]
},
{
"id": "3",
"name": "Test 3",
"tag": ["green"]
}
What I want to do now.
If the tag is Red he should output the object with the ids: 1 and 2. Tag = Green only the object with the id: 3. And so on.
I have now tried to solve this with the lodash filter.
const filteredColors = _.filter(colors, function(c) {
return _.includes(['Test 1', 'Test 2'], c.name);
});
// returns Objects with 2 Entrys = Correct
I can filter normal values, but how can I find the value in the array?

I have solved it with:
let filter = _.filter(
colors,
_.flow(
_.property('tag'),
_.partial(_.intersection, ['red', 'green']),
_.size,
),
);

There's no need for lodash, just check if the tag array includes what you're looking for:
const arr = [{
"id": "1",
"name": "Test 1",
"tag": ["blue","red", "yellow"]
},
{
"id": "2",
"name": "Test 2",
"tag": ["red", "yellow"]
},
{
"id": "3",
"name": "Test 3",
"tag": ["green"]
}];
console.log(
arr.filter(({ tag }) => tag.includes('red'))
);

Convert your array to String, and then you can check string is contain your colour or not. Like.
const items = [
{
"id": "1",
"name": "Test 1",
"tag": ["blue","red", "yellow"]
},
{
"id": "2",
"name": "Test 2",
"tag": ["red", "yellow"]
},
{
"id": "3",
"name": "Test 3",
"tag": ["green"]
}]
function findColorId(color){
return items.filter((d)=> {
if(String(d.tag).includes(color)){
return d;
}
});
}
findColorId('red');

You can use Array.prototype.filter():
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
and Array.prototype.map():
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
const colors = [{
"id": "1",
"name": "Test 1",
"tag": ["blue","red", "yellow"]
},
{
"id": "2",
"name": "Test 2",
"tag": ["red", "yellow"]
},
{
"id": "3",
"name": "Test 3",
"tag": ["green"]
}]
function filteredColors(colorsArr, c){
return colorsArr.filter(i => i.tag.includes(c)).map(i => ({id: i.id}));
}
console.log(filteredColors(colors, 'red'));
console.log(filteredColors(colors, 'green'));

This in lodash is somewhat longer than with ES6.
const data = [{ "id": "1", "name": "Test 1", "tag": ["blue","red", "yellow"] }, { "id": "2", "name": "Test 2", "tag": ["red", "yellow"] }, { "id": "3", "name": "Test 3", "tag": ["green"] }]
// lodash
const lodash = c => _.filter(data, x => _.includes(x.tag,c))
// ES6
const es6 = c => data.filter(x => x.tag.includes(c))
console.log(lodash('green'))
console.log(es6('green'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
The idea in both is to simply use _.filter / Array.filter and then _.includes / Array.includes

Related

React Native - sort array based off values in common

Hey guys I have the following array that's used to display a flatlist within my app.
Array [
Object {
"data": "Item 1",
"id": "1",
"subjects": "1,8,9,23,11,15,16,14,20",
},
Object {
"data": "Item 2",
"id": "2",
"subjects": "8,11,2,4,16,19",
},
Object {
"data": "Item 3",
"id": "3",
"subjects": "16,20,14,11,9,2",
},
Object {
"data": "Item 4",
"id": "4",
"subjects": "1,16,19",
},
]
However I would like to sort this array based off the subjects value. In the app the user can select a couple of subjects which are represented by numbers so lets say the users selected subjects are:
11, 4, 2, 1
I would like to sort the array so that the items with 3 or more subjects in common with the user are sorted to the top and then items with two and then 1 and then none so the array above should look like this after sorting:
Array [
Object {
"data": "Item 2",
"id": "2",
"subjects": "8,11,2,4,16,19",
},
Object {
"data": "Item 1",
"id": "1",
"subjects": "1,8,9,23,11,15,16,14,20",
},
Object {
"data": "Item 3",
"id": "3",
"subjects": "16,20,14,11,9,2",
},
Object {
"data": "Item 4",
"id": "4",
"subjects": "0,16,19",
},
]
How can I achieve this?
I have been searching around the array sort function:
Array.prototype.sort()
However I have only seen how to sort based off number comparisons I have never seen an array sorted based off values in common. Please could someone help me with this!
EDIT
Array [
Object {
"data": "Item 2",
"id": "2",
"subjects": "8,11,2,4,16,19",
"ranking": "green",
},
Object {
"data": "Item 1",
"id": "1",
"subjects": "1,8,9,23,11,15,16,14,20",
"ranking": "amber",
},
Object {
"data": "Item 3",
"id": "3",
"subjects": "16,20,14,11,9,2",
"ranking": "amber",
},
Object {
"data": "Item 4",
"id": "4",
"subjects": "0,16,19",
"ranking": "red",
},
]
You could create an object with counts of selected subjects and sort descending by this value.
const
data = [{ data: "Item 1", id: "1", subjects: "1,8,9,23,11,15,16,14,20" }, { data: "Item 2", id: "2", subjects: "8,11,2,4,16,19" }, { data: "Item 3", id: "3", subjects: "16,20,14,11,9,2" }, { data: "Item 4", id: "4", subjects: "1,16,19" }],
selected = [11, 4, 2, 1],
counts = data.reduce((r, { id, subjects }) => {
r[id] = subjects
.split(',')
.reduce((s, v) => s + selected.includes(+v), 0);
return r;
}, {});
data.sort((a, b) => counts[b.id] - counts[a.id]);
console.log(data);
console.log(counts);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to reformat object using its property value as property key?

how can I assign object property value as property key?
I have a set of data:
const mydata = [
{
"id": 001,
"value": "Value 1",
"title": "Title 1"
},
{
"id": 002,
"value": [
{
"Name": "Name 1",
"Age": "20"
},
{
"Name": "Name 2",
"Age": "30"
},
],
"title": "Title 2"
},
]
I want to reformat it to become:
const mydata = [
{
"Title 1": "Value 1"
},
{
"Title 2": [
{
"Name": "Name 1",
"Age": "20"
},
{
"Name": "Name 2",
"Age": "30"
},
]
},
]
I have tried this code to achieve it:
mydata.map((dt: any) => {
dt.title: dt.value
});
However, it seems not working.
Any idea how can I reformat it to the one I desire?
Thanks.
Please use following code.
Reference URL How to use a variable for a key in a JavaScript object literal?
const mydata = [
{
"id": 001,
"value": "Value 1",
"title": "Title 1"
},
{
"id": 002,
"value": [
{
"Name": "Name 1",
"Age": "20"
},
{
"Name": "Name 2",
"Age": "30"
},
],
"title": "Title 2"
},
];
let reData = [];
mydata.forEach((dt)=>{
reData.push({[dt.title]: dt.value});
});
console.log(reData);
If you want to transform the array to a different type of variable, use [reduce][1]
const mydata = [
{
id: 001,
value: "Value 1",
title: "Title 1",
},
{
id: 002,
value: [
{
Name: "Name 1",
Age: "20",
},
{
Name: "Name 2",
Age: "30",
},
],
title: "Title 2",
},
];
const data = mydata.reduce(
(acc, cur) => ({ ...acc, [cur.title]: cur.value }),
{}
);
console.log(data);
Your map function has an error, and your key assignment has another one. Let's fix it.
const newData = mydata.map((dt: any) => ({
[dt.title]: dt.value,
}));
First: You can't return an object from an arrow function without parenthesis, if you don't use it, the code will think it is a function body not an object.
Second: If you want to return a value as a key, you need put it inside "[ ]" (Square brackets)
Just that, simple mistakes, at the end you came up with the right logic to solve it
Add brackets around the return value.
Use square brackets for a computed property name.
const mydata = [
{
"id": 001,
"value": "Value 1",
"title": "Title 1"
},
{
"id": 002,
"value": [
{
"Name": "Name 1",
"Age": "20"
},
{
"Name": "Name 2",
"Age": "30"
},
],
"title": "Title 2"
},
];
const res = mydata.map(({value, title})=>({[title]: value}));
console.log(res);

parse nested JSON Data [duplicate]

This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 4 years ago.
I'm new to Javascript, ES6 , and i have hit the wall with this problem
This is the JSON that i'm getting from a webservice
{
"products": [
{
"id": 2,
"id_default_image": "21",
"price": "35.900000",
"name": [
{
"id": "1",
"value": "item 1"
},
{
"id": "2",
"value": "item 1 alternate name"
}
]
},
{
"id": 4,
"id_default_image": "4",
"price": "29.000000",
"name": [
{
"id": "1",
"value": "item 2"
},
{
"id": "2",
"value": "item 2 alternate name"
}
]
}
]
}
The name property in the above JSON is an array and i need only the value of the first element. The desired output would be like below
{
"products": [
{
"id": 2,
"id_default_image": "21",
"price": "35.900000",
"name": "item 1"
},
{
"id": 4,
"id_default_image": "4",
"price": "29.000000",
"name": "item 2"
}
]
}
I'm working on a react-native project. What would be the easiest way to achieve this? Any help would be greatly appreciated. Thanks.
Similar to Ele's answer but if you don't want to change the original object. You can use map to iterate over the product objects and return a new products array:
const data = {"products":[{"id":2,"id_default_image":"21","price":"35.900000","name":[{"id":"1","value":"item 1"},{"id":"2","value":"item 1 alternate name"}]},{"id":4,"id_default_image":"4","price":"29.000000","name":[{"id":"1","value":"item 2"},{"id":"2","value":"item 2 alternate name"}]}]};
const products = data.products.map(obj => ({ ...obj, name: obj.name[0].value }));
console.log(products);
Also used: spread syntax
Well, you can use the function forEach or a simple for-loop and assign the first value to the attribute name.
let obj = { "products": [ { "id": 2, "id_default_image": "21", "price": "35.900000", "name": [ { "id": "1", "value": "item 1" }, { "id": "2", "value": "item 1 alternate name" } ] }, { "id": 4, "id_default_image": "4", "price": "29.000000", "name": [ { "id": "1", "value": "item 2" }, { "id": "2", "value": "item 2 alternate name" } ] } ]}
obj.products.forEach(o => (o.name = o.name[0].value));
console.log(obj);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Try this
const productsArray = products.map((product, index) => {
const obj = {};
obj["id"] = product["id"];
obj["id_default_image"] = product["id_default_image"];
obj["price"] = product["price"],
obj["name"] = product.name[0].value;
return obj;
});
const obj = {};
obj.products = productsArray;
console.log(obj);//will print you the desired output you want

Most performant way to sort a deeply nested array of objects by another deeply nested array of objects

As an example - I've included a one element array that contains an object that has a Children key, which is an array of objects and each object also has its' own Children key that contains another array.
[
{
"Id": "1",
"Children": [
{
"Id": "2",
"Children": [
{
"Id": "10",
"DisplayName": "3-4",
},
{
"Id": "1000",
"DisplayName": "5-6",
},
{
"Id": "100",
"DisplayName": "1-2",
},
]
}
]
}
]
There is a second array of objects that I would like to compare the first array of objects to, with the intention of making sure that the first array is in the same order as the second array of objects, and if it is not - then sort until it is.
Here is the second array:
[
{
"Id": "1",
"Children": [
{
"Id": "2",
"Children": [
{
"Id": "100",
"DisplayName": "1-2",
},
{
"Id": "10",
"DisplayName": "3-4",
},
{
"Id": "1000",
"DisplayName": "5-6",
},
]
}
]
}
]
The data that this will run on can be up in the tens of thousands - so performance is paramount.
What I'm currently attempting is using a utility method to convert each element of the second array into a keyed object of objects e.g.
{
1: {
"Id": "1",
"Children": [
{
"Id": "2",
"Children": [
{
"Id": "4",
"DisplayName": "3-4",
},
{
"Id": "3",
"DisplayName": "1-2",
},
]
}
]
}
}
This allows fast look up from the top level. I'm wondering if I should continue doing this all the way down or if there is an idiomatic way to accomplish this. I considered recursion as well.
The order of the already sorted array is not based on Id - it is arbitrary. So the order needs to be preserved regardless.
Assuming same depth and all Id's exist in each level of each object use a recursive function that matches using Array#findIndex() in sort callback
function sortChildren(main, other) {
other.forEach((o, i) => {
if (o.children) {
const mChilds = main[i].children, oChilds = o.children;
oChilds.sort((a, b) => {
return mChilds.findIndex(main => main.Id === a.Id) - mChilds.findIndex(main => main.Id === b.Id)
});
// call function again on this level passing appropriate children arrays in
sortChildren(mChilds, oChilds)
}
})
}
sortChildren(data, newData);
console.log(JSON.stringify(newData, null, ' '))
<script>
var data = [{
"Id": "1",
"Children": [{
"Id": "2",
"Children": [{
"Id": "3",
"DisplayName": "1-2",
},
{
"Id": "4",
"DisplayName": "3-4",
},
]
}]
}]
var newData = [{
"Id": "1",
"Children": [{
"Id": "2",
"Children": [{
"Id": "4",
"DisplayName": "3-4",
},
{
"Id": "3",
"DisplayName": "1-2",
},
]
}]
}]
</script>

Comparing arrays of objects and remove duplicate [duplicate]

This question already has answers here:
Remove duplicates in an object array Javascript
(10 answers)
Closed 5 years ago.
I have an array containing arrays of objects which I need to compare.
I've looked through multiple similar threads, but I couldn't find a proper one that compares multiple arrays of objects (most are comparing two arrays of objects or just comparing the objects within a single array)
This is the data (below is a JSFiddle with code sample)
const data = [
[
{
"id": "65",
"name": "Some object name",
"value": 90
},
{
"id": "89",
"name": "Second Item",
"value": 20
}
],
[
{
"id": "89",
"name": "Second Item",
"value": 20
},
{
"id": "65",
"name": "Some object name",
"value": 90
}
],
[
{
"id": "14",
"name": "Third one",
"value": 10
}
]
]
I want to remove all duplicate arrays of objects, regardless of the length of data (there could be a lot more records).
I managed to get the unique ones extracted into an object:
const unique = data.reduce(function(result, obj) {
return Object.assign(result, obj)
}, [])
That doesn't work for me though, because I need 1 of the duplicated arrays to remain and the returned data to be an array as well, instead of an object. E.g.:
// result I need
[
[
{
"id":"65",
"name":"Some object name",
"value":90
},
{
"id":"89",
"name":"Second Item",
"value":20
}
],
[
{
"id":"14",
"name":"Third one",
"value":10
}
]
]
So how do I compare each array of objects to the others in the parent array and preserve one of each duplicated or unique array of objects?
JSFiddle
you can achieve so by using function.As below. Not sure about best optimum way of doing so.
var testArray = [
[
{
"id": "65",
"name": "Some object name",
"value": 90
},
{
"id": "89",
"name": "Second Item",
"value": 20
}
],
[
{
"id": "89",
"name": "Second Item",
"value": 20
},
{
"id": "65",
"name": "Some object name",
"value": 90
}
],
[
{
"id": "14",
"name": "Third one",
"value": 10
}
]
]
function removeDuplicatesFromArray(arr){
var obj={};
var uniqueArr=[];
for(var i=0;i<arr.length;i++){
if(!obj.hasOwnProperty(arr[i])){
obj[arr[i]] = arr[i];
uniqueArr.push(arr[i]);
}
}
return uniqueArr;
}
var newArr = removeDuplicatesFromArray(testArray);
console.log(newArr);
const data = [
[
{
"id": "65",
"name": "Some object name",
"value": 90
},
{
"id": "89",
"name": "Second Item",
"value": 20
}
],
[
{
"id": "89",
"name": "Second Item",
"value": 20
},
{
"id": "65",
"name": "Some object name",
"value": 90
}
],
[
{
"id": "14",
"name": "Third one",
"value": 10
}
]
];
const temp = {};
const result = [];
data.forEach(itemArr => {
const items = itemArr.filter(item => {
const isUnique = temp[`${item.id}-${item.name}-${item.value}`] === undefined;
temp[`${item.id}-${item.name}-${item.value}`] = true;
return isUnique;
});
if (items.length !== 0)
result.push(items);
});
console.log(result);

Categories

Resources