Find items in the array based on the inner array condition - arrays

How to find id in an array that is inside of an array of objects
Example:
let arrayobjects = [{
id: 1,
name: "oinoin",
description: ["one", "two", "three"]
}, {
id: 2,
name: "zatata",
description: ["four", "five", "six"]
}];
How can I find the id of the word "two" ?

If you need more than one item, you can filter the array via Array#filter, check if property description for each item contains word two via Array#includes (ES7), then map the result to get only id of those items using Array#map.
let arrayobjects = [
{ id: 1, name: "oinoin", description: ["one", "two", "three"] },
{ id: 2, name: "zatata", description: ["four", "five", "six"] }
];
const ids = arrayobjects.filter(item => item.description.includes('two'))
.map(item => item.id);
console.log(ids);
If you have only one item, you can just use Array#find and do same checking
let arrayobjects = [
{ id: 1, name: "oinoin", description: ["one", "two", "three"] },
{ id: 2, name: "zatata", description: ["four", "five", "six"] }
];
const item = arrayobjects.find(item => item.description.includes('two'));
console.log(item.id);

This snippet might be what you are looking for
arrayobjects.filter( ele => ele.description.includes("two")).map(ele => ele.id)
output :[1]

There may be more efficient way, but i some how find a solution. iterate through the array and match the array item.
var arrayobjects = [{ id: 1, name: "oinoin", description: ["one", "two", "three"]}, { id: 2, name: "zatata", description: ["four", "five", "six"]}];
arrayobjects.forEach(item => {
if(item.description.indexOf('two') != -1 ){
console.log(item.id)
}
})

You can try with indexOf too
arrayobjects.filter(f=>f.description.indexOf('two')>-1)[0].id
let arrayobjects = [
{
id: 1,
name: "oinoin",
description: ["one", "two", "three"]
}, {
id: 2,
name: "zatata",
description: ["four", "five", "six"]
}
];
console.log(arrayobjects.filter(f=>f.description.indexOf('two')>-1)[0].id);
Note
.filter returns an array. So if multiple items are found with two in description then you do not use index [0]. This is just an example of one item in array.

For examples sake, here is a version with old javascript.
var arrayobjects = [
{
id: 1,
name: "oinoin",
description: ["one", "two", "three"]
}, {
id: 2,
name: "zatata",
description: ["four", "five", "six"]
}
];
function findId (desc, arr) {
var idx, arrObjLen = arr.length, results = [];
// Iterate through the first array
for (idx = 0; idx < arrObjLen; idx ++) {
// If the value exists in the 'description' array
if (arr[idx].description.indexOf(desc) > -1) {
// Add it to the results array
results.push(arr[idx].id)
}
}
return results;
}
console.log('Results:', findId('five', arrayobjects));
You could also use Array#reduce if you want to minimise the amount of code you're using:
const arrayobjects = [
{
id: 1,
name: "oinoin",
description: ["one", "two", "three"]
}, {
id: 2,
name: "zatata",
description: ["four", "five", "six"]
}
];
console.log(
arrayobjects.reduce((col, { id, description }) =>
// If description contains the desired value
description.includes('two')
// Add the id to the collector array
? [ ...col, id ] : col, [])
);

Related

Grouping Data in TypeScript Array

I have JSON data that looks like this:
[
{
"id": 1,
"tags": [
"Test 1",
"Test 2",
"Test 3"
]
},
{
"id": 2,
"tags": [
"Test 2",
"Test 3",
"Test 4"
]
},
{
"id": 3,
"tags": [
"Test 3",
"Test 4"
]
}
]
I would like to transform this into data that looks like this:
[
{
"name": "Test 1",
"count": 1
},
{
"name": "Test 2",
"count": 2
},
{
"name": "Test 3",
"count": 3
},
{
"name": "Test 4",
"count": 1
}
]
I can think of some brute ways to do this, but I'm hoping there is something more performant and a little sexier? Possibly using .groupBy() or .reduce()?
Thanks for taking the time to check out my question.
I would:
parse the json
gather all tags in an array
count occurences using one of the approaches in Counting the occurrences / frequency of array elements
interface Item {
id: number,
tags: string[]
}
function countOccurences(a: string[]) {
return a.reduce(function (acc: {[key: string]: number}, curr: string) {
acc[curr] ??= 0;
acc[curr]++;
return acc;
}, {});
}
const data: Item[] = JSON.parse(json);
const tagOccurences = countOccurences(data.flatMap(o => o.tags))
Playground link
You can use reduce inside reduce to group the tags.
const array = [{
id: 1,
tags: ['Test 1', 'Test 2', 'Test 3'],
},
{
id: 2,
tags: ['Test 2', 'Test 3', 'Test 4'],
},
{
id: 3,
tags: ['Test 3', 'Test 4'],
},
];
const frequencies = Object.values(array.reduce((acc, curr) =>
curr.tags.reduce(
(nAcc, tag) => ((nAcc[tag] ??= {name: tag,count: 0}),nAcc[tag].count++,nAcc),
acc
), {}
));
console.log(frequencies);
In TypeScript:
const array = [{
id: 1,
tags: ['Test 1', 'Test 2', 'Test 3'],
},
{
id: 2,
tags: ['Test 2', 'Test 3', 'Test 4'],
},
{
id: 3,
tags: ['Test 3', 'Test 4'],
},
];
type Frequency = {
name: string,
count: number
}
const frequencies = Object.values(array.reduce((acc, curr) =>
curr.tags.reduce(
(nAcc, tag) => ((nAcc[tag] ??= {name: tag,count: 0}),nAcc[tag].count++,nAcc),
acc
), {} as Record<string, Frequency>
));
console.log(frequencies);
Playground
Using for...of iteration and a Map as a cache is a very straightforward approach... and sexy.
TS Playground
type TagsWithId = {
id: number;
tags: string[];
};
type TagCount = {
count: number;
name: string;
};
function verySexyTagCounter (input: TagsWithId[]): TagCount[] {
const map = new Map<string, number>();
for (const {tags} of input) {
for (const name of tags) {
map.set(name, (map.get(name) ?? 0) + 1);
}
}
return [...map.entries()].map(([name, count]) => ({name, count}));
}
const json = `[{"id":1,"tags":["Test 1","Test 2","Test 3"]},{"id":2,"tags":["Test 2","Test 3","Test 4"]},{"id":3,"tags":["Test 3","Test 4"]}]`;
const input: TagsWithId[] = JSON.parse(json);
const result = verySexyTagCounter(input);
console.log(result);

Sort array based on the order from another array Swift

I have the following tow arrays:
fetchedProducts = [
[name: "productName20", id: 20],
[name: "productName3", id: 3],
[name: "productName1", id: 1]
]
sortedProducts = [
[productName1: "1"], // I know the numbers here are string; I need them to be string
[productName20: "20"],
[productName3: "3"]
]
Now I need to sort fetchedProducts based on the order of sortedProducts so it would end up looking like the following:
fetchedProducts = [
[name: "productName1", id: 1],
[name: "productName20", id: 20],
[name: "productName3", id: 3]
]
You can try the following in Swift. Note the dictionaries in Swift are unordered so you have to use arrays for ordered collections:
let fetchedProducts = [
(name: "productName20", id: 20),
(name: "productName3", id: 3),
(name: "productName1", id: 1),
]
let sortedProducts = [
("productName1", "1"),
("productName20", "20"),
("productName3", "3"),
]
let sortedFetchedProducts = sortedProducts
.compactMap { s in
fetchedProducts.first(where: { s.1 == String($0.id) })
}
print(sortedFetchedProducts)
// [(name: "productName1", id: 1), (name: "productName20", id: 20), (name: "productName3", id: 3)]
JavaScipt realisation:
const fetchedProducts = [
{name: "productName20", id: 20},
{name: "productName3", id: 3},
{name: "productName1", id: 1}
];
const sortedProducts = [
{productName1: "1"}, // I know the numbers here are string; I need them to be string
{productName20: "20"},
{productName3: "3"}
];
const sortProducts = (fetchedProducts, sortedProducts) => {
// Extract ordered id from the sortedProducts array
const orderIds = sortedProducts.map(sorted => +Object.values(sorted));
// Find product by sorted id and put into new array
const sortedFetchedProducts = [];
orderIds.forEach(id => {
let product = fetchedProducts.find(item => item.id === id);
sortedFetchedProducts.push(product);
});
return sortedFetchedProducts;
}
const sortedFetchedProducts = sortProducts(fetchedProducts, sortedProducts);
console.log(sortedFetchedProducts);
Output:
[
{ name: 'productName1', id: 1 },
{ name: 'productName20', id: 20 },
{ name: 'productName3', id: 3 }
]

Write a loop array method to filter specific value

Supposing I have these two objects :
struct Product {
let id: Int
let title: String
let price: Int
let categoryId: Int
}
struct Category {
let id: Int
let name: String
}
Then I create two arrays containing those objects :
let products = [Product(id: 1, title: "snake", price: 20, categoryId: 1),
Product(id: 2, title: "soap", price: 20, categoryId: 2),
Product(id: 3, title: "cream", price: 20, categoryId: 3),
Product(id: 4, title: "dog", price: 20, categoryId: 1),
Product(id: 5, title: "car", price: 20, categoryId: 4),
]
let categorieItems = [Category(id: 1, name: "animal"),
Category(id: 2, name: "chemichal"),
Category(id: 3, name: "food"),
Category(id: 4, name: "travel"),
]
I want to create a new array which contains the names of all the product categories :
func handleCategories() -> [String] {
var categoryNames = [String]()
for product in products {
for categorieItem in categorieItems {
if product.categoryId == categorieItem.id {
categoryNames.append(category.name)
}
}
}
return categoryNames
}
This method works but I want to write one with closure (I guess map() should works)
The result should be :
categoryNames = ["animal", "chemichal", "food", "animal", "travel"]
Make a dictionary that keys the category by id, and map each product into a category by looking up its categoryId in that dict.
I used a force unwrap, assuming that products don't contain any invalid categoryIds.
struct Product {
let id: Int
let title: String
let price: Int
let categoryId: Int
}
struct Category {
let id: Int
let name: String
}
let products = [
Product(id: 1, title: "snake", price: 20, categoryId: 1),
Product(id: 2, title: "soap", price: 20, categoryId: 2),
Product(id: 3, title: "cream", price: 20, categoryId: 3),
Product(id: 4, title: "dog", price: 20, categoryId: 1),
Product(id: 5, title: "car", price: 20, categoryId: 4),
]
let categorieItems = [
Category(id: 1, name: "animal"),
Category(id: 2, name: "chemichal"),
Category(id: 3, name: "food"),
Category(id: 4, name: "travel"),
]
let categoriesById = Dictionary(uniqueKeysWithValues:
categorieItems.map { (key: $0.id, value: $0) }
)
let productCategoryNames = products.map { categoriesById[$0.categoryId]!.name }
print(productCategories)

Unique Array by comparing elements of array React JS

I have this array
array = [
{id: "one", title: "new 1"},
{id: "two", parent_id: "132132", title: "new 2"},
{id: "three", parent_id: "132132", title: "new 3"},
{id: "four", parent_id: "132132", title: "new 1"},
{id: "one", parent_id: "132132", title: "new 1"}
]
We need
array = [
{id: "two", parent_id: "132132", title: "new 2"},
{id: "three", parent_id: "132132", title: "new 3"},
{id: "four", parent_id: "132132", title: "new 1"},
{id: "one", parent_id: "132132", title: "new 1"}
]
We need to compare elements to get unique array with different avoiding other elements
I have tried using this method
uniqueArray = (arr) => {
return arr.filter((e, i, arr) => arr.findIndex(e2 => Object.keys(e2).every(prop => e2[prop] === e[prop])) === i);
};
I prefer Array.reduce for this kind of things:
const filteredArr = arr.reduce((acc, current) => {
const exists = acc.find(item => item.id === current.id);
if (!exists) {
return acc.concat([current]);
} else {
return acc;
}
}, []);
If I understand you correctly, you want to return object without the property of parentId. If so you can use this.
array.filter(arr => arr.hasOwnProperty("parentId"))

How to filter multiple objects from a list objects by a property array?

I have a object array in which each object contain an id and a name and a separate array contains a set of ids. I want to filter first array based on the second array.
const data= [
{
id: 1,
name: 'name1'
},
{
id: 2,
name: 'name2'
},
{
id: 3,
name: 'name3'
},
{
id: 4,
name: 'name4'
}
];
const array = [1,3,4];
const expectedResult= [
{
id: 1,
name: 'name1'
},
{
id: 3,
name: 'name3'
},
{
id: 4,
name: 'name4'
}
];
Use .filter and .includes
const data= [
{
id: 1,
name: 'name1'
},
{
id: 2,
name: 'name2'
},
{
id: 3,
name: 'name3'
},
{
id: 4,
name: 'name4'
}
];
const array = [1, 3, 4]
const result = data.filter((item) => {
//gives us items that passes a condition
return array.includes(item.id)
})
console.log(result)

Resources