I'm writing a program that first must match an item with name === searchValue, then i need his programParent item recursively. Example: first match is: { id: '25', name: 'ventas OUT Personal plus', programParent: '24' } so his parent is: { id: '24', name: 'ventas OUT Personal', programParent: '23' } & his parent is: { id: '23', name: 'ventas', programParent: '' }. An empty string represents the last parent.
const programs = [
{ id: '23', name: 'ventas', programParent: '' },
{ id: '24', name: 'ventas OUT Personal', programParent: '23' },
{ id: '25', name: 'ventas OUT Personal plus', programParent: '24' },
{ id: '26', name: 'ventas IN Hogares', programParent: '23' },
{ id: '27', name: 'Ad Hoc', programParent: '' },
{ id: '28', name: 'Ad Hoc asd', programParent: '27' },
{ id: '29', name: 'Ad Hoc 123', programParent: '27' },
{ id: '30', name: 'ventas IN Personal plus', programParent: '26' },
]
const searchValue = 'ventas OUT Personal plus'
const filteredPrograms = programs.filter(x => x.name === searchValue)
console.log(filteredPrograms)
const result = []
for (let i = 0; i < filteredPrograms.length; i++) {
for (let j = 0; j < programs.length; j++) {
if (filteredPrograms[i].programParent === programs[j].id) {
result.push(programs[j])
}
}
}
console.log(result)
// const expected = [
// { id: '25', name: 'ventas OUT Personal plus', programParent: '24' },
// { id: '24', name: 'ventas OUT Personal', programParent: '23' },
// { id: '23', name: 'ventas', programParent: '' }
// ]
You could take a single loop for searching and building a hash table for all id and their objects.
At the end get the last object of result and take the parent until no more parents are available.
const
programs = [{ id: '23', name: 'ventas', programParent: '' }, { id: '24', name: 'ventas OUT Personal', programParent: '23' }, { id: '25', name: 'ventas OUT Personal plus', programParent: '24' }, { id: '26', name: 'ventas IN Hogares', programParent: '23' }, { id: '27', name: 'Ad Hoc', programParent: '' }, { id: '28', name: 'Ad Hoc asd', programParent: '27' }, { id: '29', name: 'Ad Hoc 123', programParent: '27' }, { id: '30', name: 'ventas IN Personal plus', programParent: '26' }],
searchValue = 'ventas OUT Personal plus',
result = [],
ids = {};
for (const program of programs) {
if (program.name === searchValue) result.push(program);
ids[program.id] = program;
}
while (result.at(-1).programParent)
result.push(ids[result.at(-1).programParent]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Related
This code is working but i would like to make it with array methods. The condition of filtering is: if programParent is empty string -> must pass, if id equals to some programParent -> must pass. I was trying to make it with filter method and find, but i need some help. Thanks in advance.
let programsRes = [
{ id: '23', name: 'ventas', programParent: '' },
{ id: '24', name: 'ventas OUT Personal', programParent: '23' },
{ id: '25', name: 'ventas OUT Personal plus', programParent: '24' },
{ id: '26', name: 'ventas IN Hogares', programParent: '23' },
{ id: '27', name: 'Ad Hoc', programParent: '' },
{ id: '28', name: 'Ad Hoc asd', programParent: '27' },
{ id: '29', name: 'Ad Hoc 123', programParent: '27' },
{ id: '30', name: 'ventas IN Personal plus', programParent: '26' },
]
let expected = [
{ id: '23', name: 'ventas', programParent: '' },
{ id: '24', name: 'ventas OUT Personal', programParent: '23' },
{ id: '26', name: 'ventas IN Hogares', programParent: '23' },
{ id: '27', name: 'Ad Hoc', programParent: '' },
]
let result = []
for (let i = 0; i < programsRes.length; i++) {
for (let j = 0; j < programsRes.length; j++) {
if (programsRes[i].programParent === '') {
result.push(programsRes[i])
break;
}
if (programsRes[i].id === programsRes[j].programParent) {
result.push(programsRes[i])
break;
}
}
}
console.log(result)
let programsRes = [
{ id: '23', name: 'ventas', programParent: '' },
{ id: '24', name: 'ventas OUT Personal', programParent: '23' },
{ id: '25', name: 'ventas OUT Personal plus', programParent: '24' },
{ id: '26', name: 'ventas IN Hogares', programParent: '23' },
{ id: '27', name: 'Ad Hoc', programParent: '' },
{ id: '28', name: 'Ad Hoc asd', programParent: '27' },
{ id: '29', name: 'Ad Hoc 123', programParent: '27' },
{ id: '30', name: 'ventas IN Personal plus', programParent: '26' },
];
let result = programsRes.filter(program =>
program.programParent === '' ||
programsRes.some(item => item.programParent === program.id));
console.log(result)
I have following array which consist of json objects:
items = [
{
id: '1',
name: 'Josh',
transactionDate: '2012-08-10',
creditAmount: '200',
numberBank: '12345',
},
{
id: '1',
name: 'Josh',
transactionDate: '2012-08-14',
creditAmount: '159',
numberBank: '12345',
},
{
id: '1',
name: 'Josh',
transactionDate: '2012-08-15',
creditAmount: '3421',
numberBank: '12345',
},
{
id: '2',
name: 'George',
transactionDate: '2012-09-15',
creditAmount: '6000',
numberBank: '13345',
},
{
id: '2',
name: 'George',
transactionDate: '2012-09-16',
creditAmount: '6565',
numberBank: '13345',
}
]
I want to separate the array index for each same id
as an example :
[
{
id: '1',
name: 'Josh',
transactionDate: '2012-08-10',
creditAmount: '200',
numberBank: '12345',
},
{
id: '1',
name: 'Josh',
transactionDate: '2012-08-14',
creditAmount: '159',
numberBank: '12345',
},
{
id: '1',
name: 'Josh',
transactionDate: '2012-08-15',
creditAmount: '3421',
numberBank: '12345',
}
],
[
{
id: '2',
name: 'George',
transactionDate: '2012-09-15',
creditAmount: '6000',
numberBank: '13345',
},
{
id: '2',
name: 'George',
transactionDate: '2012-09-16',
creditAmount: '6565',
numberBank: '13345',
}
]
How to do like that ? thanks
you can use reduce to group by id and then the values of the resultant using Object.values
EDIT
??= is the Logical nullish assignment. The right hand side will be assigned whenever the left hand side is null or undefined.
let items = [ { id: '1', name: 'Josh', transactionDate: '2012-08-10', creditAmount: '200', numberBank: '12345', }, { id: '1', name: 'Josh', transactionDate: '2012-08-14', creditAmount: '159', numberBank: '12345', }, { id: '1', name: 'Josh', transactionDate: '2012-08-15', creditAmount: '3421', numberBank: '12345', }, { id: '2', name: 'George', transactionDate: '2012-09-15', creditAmount: '6000', numberBank: '13345', }, { id: '2', name: 'George', transactionDate: '2012-09-16', creditAmount: '6565', numberBank: '13345', } ]
const res = Object.values(items.reduce((acc,curr)=> {
acc[curr.id]??=[] //similar to acc[curr.id] = acc[curr.id] || [] in this case
acc[curr.id].push(curr)
return acc
},{}))
console.log(res)
I am trying to compare 2 objects by their property and the values Strictly using forloop. If the value of the "name" or another property matches up with each other, I want to push the property and value to value3.
Once value3 is logged, I want the response like this:
{
name: 'dog',
surname: 'good',
skills: 'programming',
age: '22'
},
{
name: 'cat',
surname: 'soft',
skills: 'engineer'
age: '12'
},
{
name: 'elephant',
surname: 'big',
skills: 'programming'
age: '23'
}
Here is the code:
var values1 = [
{
name: 'dog',
surname: 'good',
skills: 'programming'
},
{
name: 'cat',
surname: 'soft',
skills: 'engineer'
},
{
name: 'elephant',
surname: 'big',
skills: 'programming'
}
]
var values2 = [
{
name: 'cat',
food: 'fish',
age: '12'
},
{
name: 'elephant',
food: 'leafs',
age: '13'
},
{
lastname: 'dog',
food: 'treats',
age: '22'
}
]
// push into this empty object array
var values3 = [{}]
console.log(values3)
The most generic approach which fulfills all of the OP's requirements should be based on Array.prototype.reduce. Its advantage comes with utilizing the additionally passed optional initial value as kind of configurable collector/accumulator object which will carry all the needed additional information / functions / result. Thus one can provide a reusable function with a customizable context/environment which one can adapt to ones needs.
var values1 = [{
name: 'dog',
surname: 'good',
skills: 'programming',
}, {
name: 'cat',
surname: 'soft',
skills: 'engineer',
}, {
name: 'elephant',
surname: 'big',
skills: 'programming',
}];
var values2 = [{
name: 'cat',
food: 'fish',
age: '12'
}, {
name: 'elephant',
food: 'leafs',
age: '13'
}, {
lastname: 'dog',
food: 'treats',
age: '22'
}];
function mergeItemsOfSameEntry(collector, item) {
const {
getSameEntryValue,
getMergeSubType,
comparisonItems,
result
} = collector;
const itemValue = getSameEntryValue(item);
const comparisonItem = comparisonItems
.find(cItem => getSameEntryValue(cItem) === itemValue);
if (comparisonItem !== null) {
result.push({
...item,
...getMergeSubType(comparisonItem),
});
}
return collector;
}
const values3 = values1.reduce(mergeItemsOfSameEntry, {
getSameEntryValue: item => item.name ?? item.lastname,
getMergeSubType: ({ age }) => ({ age }),
comparisonItems: values2,
result: [],
}).result;
console.log({ values3 });
.as-console-wrapper { min-height: 100%!important; top: 0; }
If you just want the key and value pair, you can do something like this:
var values1 = [
{
name: 'dog',
surname: 'good',
skills: 'programming'
},
{
name: 'cat',
surname: 'soft',
skills: 'engineer'
},
{
name: 'elephant',
surname: 'big',
skills: 'programming'
}
]
var values2 = [
{
name: 'cat',
food: 'fish',
age: '12'
},
{
name: 'elephant',
food: 'leafs',
age: '13'
},
{
lastname: 'dog',
food: 'treats',
age: '22'
}
]
// push into this empty object array
var values3 = [];
values1.forEach(eachValue1Obj => {
const keys = Object.keys(eachValue1Obj);
keys.forEach(eachKey => {
values2.forEach(eachValue2Obj => {
if (
eachValue1Obj[eachKey] &&
eachValue2Obj[eachKey] &&
eachValue1Obj[eachKey] === eachValue2Obj[eachKey]
) {
const x = {
key: eachKey,
value: eachValue1Obj[eachKey]
};
values3.push(x)
}
})
})
})
console.log('Values 3 Array ==>', values3);
I am trying to compare 2 objects by their property and the values. If the value of the "name" property matches up with each other, I want to push the property and value to value3.
Once value3 is logged, I want the response like this:
{
name: 'dog',
surname: 'good',
skills: 'programming',
age: '22'
},
{
name: 'cat',
surname: 'soft',
skills: 'engineer'
age: '12'
},
{
name: 'elephant',
surname: 'big',
skills: 'programming'
age: '23'
}
Here is the code:
var values1 = [
{
name: 'dog',
surname: 'good',
skills: 'programming'
},
{
name: 'cat',
surname: 'soft',
skills: 'engineer'
},
{
name: 'elephant',
surname: 'big',
skills: 'programming'
}
]
var values2 = [
{
name: 'cat',
food: 'fish',
age: '12'
},
{
name: 'elephant',
food: 'leafs',
age: '13'
},
{
name: 'dog',
food: 'treats',
age: '22'
}
]
// push into this empty object array
var values3 = [{}]
console.log(values3)
const values1 = [
{ name: 'dog', surname: 'good', skills: 'programming' },
{ name: 'cat', surname: 'soft', skills: 'engineer' },
{ name: 'elephant', surname: 'big', skills: 'programming' }
]
const values2 = [
{ name: 'cat', food: 'fish', age: '12' },
{ name: 'elephant', food: 'leafs', age: '13' },
{ name: 'dog', food: 'treats', age: '22' }
]
const values3 = values1.map((value1) => {
return Object.assign(value1, { age: values2.filter(value2 => value2.name === value1.name)[0].age })
})
console.log(values3)
The code above will only work if for each name in values1 an object with name exists in values2. If not use this code:
const values3 = values1.map((value1) => {
const found = values2.find(value2 => value2.name === value1.name)
return Object.assign(value1, { age: found ? found.age : undefined })
})
I need to return the string with category and type together when use input the type id(which is unique) , I am pretty much done with that but I am unable to fetch root category .
My solution return 'Terrace' but I need 'Rural / Terrace'.
I think I am making things over complicated
let obj =[
{
category: 'Residential',
category_id: 1,
types: [{name: 'House', id: 1},{name: 'Townhouse / Villa', id: 3},{name: 'House and Land', id: 5},{name: 'Duplex', id: 4},{name: 'Land', id: 6},{name: 'Terrace', id: 16},{name: 'Apartment/Unit', id: 2},{name: 'Relocatable', id: 7}]
},
{
category: 'Commercial',
category_id: 2,
types: [{name: 'Office', id: 12},{name: 'House', id: 8},{name: 'Land', id: 9},{name: 'Shop', id: 10},{name: 'Factory', id: 11}]
},
{
category: 'Rural',
category_id: 3,
types: [{name: 'House', id: 17},{name: 'House and Land', id: 14},{name: 'Land', id: 13},{name: 'Terrace', id: 15}]
}
];
console.log(obj.map(o=>o.types).reduce((acc, val) => acc.concat(val), []).find(inner_obj=>inner_obj.id==15).name);
I might try something like this. Use reduce() to go through the main items, then use find() to see if you have a matching item. If so, push what you need to the array.
let obj =[{category: 'Residential',category_id: 1,types: [{name: 'House', id: 1},{name: 'Townhouse / Villa', id: 3},{name: 'House and Land', id: 5},{name: 'Duplex', id: 4},{name: 'Land', id: 6},{name: 'Terrace', id: 16},{name: 'Apartment/Unit', id: 2},{name: 'Relocatable', id: 7}]}, {category: 'Commercial',category_id: 2,types: [{name: 'Office', id: 12},{name: 'House', id: 8},{name: 'Land', id: 9},{name: 'Shop', id: 10},{name: 'Factory', id: 11}]},{category: 'Rural',category_id: 3,types: [{name: 'House', id: 17},{name: 'House and Land', id: 14},{name: 'Land', id: 13},{name: 'Terrace', id: 15}]}];
let found = obj.reduce((a, c) => {
let found = c.types.find(t => t.id === 15)
if (found) a.push({category: c.category, name:found.name})
return a
}, [])
console.log(found)
I could potentially return more than one item if there was more than one item with id===15. In this case it's not clear what should happen, but returning them all seems reasonable.
EDIT: if you know id is unique
If you know there is only one of each id, you can exit early, which might save some time in big searches:
let obj =[{category: 'Residential',category_id: 1,types: [{name: 'House', id: 1},{name: 'Townhouse / Villa', id: 3},{name: 'House and Land', id: 5},{name: 'Duplex', id: 4},{name: 'Land', id: 6},{name: 'Terrace', id: 16},{name: 'Apartment/Unit', id: 2},{name: 'Relocatable', id: 7}]}, {category: 'Commercial',category_id: 2,types: [{name: 'Office', id: 12},{name: 'House', id: 8},{name: 'Land', id: 9},{name: 'Shop', id: 10},{name: 'Factory', id: 11}]},{category: 'Rural',category_id: 3,types: [{name: 'House', id: 17},{name: 'House and Land', id: 14},{name: 'Land', id: 13},{name: 'Terrace', id: 15}]}];
function find(id, obj) {
for (prop of obj){
let found = prop.types.find(t => t.id === id)
if (found) return [prop.category, found.name]
}
}
console.log(find(15, obj))
Why not just something simple like this?
let obj = [{ category: 'Residential', category_id: 1, types: [{ name: 'House', id: 1 }, { name: 'Townhouse / Villa', id: 3 }, { name: 'House and Land', id: 5 }, { name: 'Duplex', id: 4 }, { name: 'Land', id: 6 }, { name: 'Terrace', id: 16 }, { name: 'Apartment/Unit', id: 2 }, { name: 'Relocatable', id: 7 }] }, { category: 'Commercial', category_id: 2, types: [{ name: 'Office', id: 12 }, { name: 'House', id: 8 }, { name: 'Land', id: 9 }, { name: 'Shop', id: 10 }, { name: 'Factory', id: 11 }] }, { category: 'Rural', category_id: 3, types: [{ name: 'House', id: 17 }, { name: 'House and Land', id: 14 }, { name: 'Land', id: 13 }, { name: 'Terrace', id: 15 }] } ];
for (let elem of obj) {
const typeFound = elem.types.find(type => type.id === 15);
if (typeFound) {
console.log(elem.category + " " + typeFound.name);
break;
}
}
Here's one way to do it. First, flatten the possible results to an array of results like [{id: 15, name: "Rural / Terrace"}, ...], then find the specific element you want.
let obj =[
{
category: 'Residential',
category_id: 1,
types: [{name: 'House', id: 1},{name: 'Townhouse / Villa', id: 3},{name: 'House and Land', id: 5},{name: 'Duplex', id: 4},{name: 'Land', id: 6},{name: 'Terrace', id: 16},{name: 'Apartment/Unit', id: 2},{name: 'Relocatable', id: 7}]
},
{
category: 'Commercial',
category_id: 2,
types: [{name: 'Office', id: 12},{name: 'House', id: 8},{name: 'Land', id: 9},{name: 'Shop', id: 10},{name: 'Factory', id: 11}]
},
{
category: 'Rural',
category_id: 3,
types: [{name: 'House', id: 17},{name: 'House and Land', id: 14},{name: 'Land', id: 13},{name: 'Terrace', id: 15}]
}
];
const flatTypes = obj.map(cat =>
cat.types.map(type => {
return {
id: type.id,
name: `${cat.category} / ${type.name}`
};
})
).reduce((flatTypes, typeArray) =>
flatTypes.concat(typeArray)
, []);
const result = flatTypes.find(type => type.id === 15).name;
console.log(result);