2

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);

3 Answers 3

1

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))

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks , sometimes one liners are really ugly :)
1

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;
  }
}

Comments

0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.