4

Im trying to create a filter function where it can return a result of data that matches the value that i am looking for , from the given set of string keys

example of array:

let data = [
 { id:1 , data:{ name:"sample1",address:{ cat:"business" } } },
 { id:2 , data:{ name:"sample2",address:{ cat:"office"  }  } },
 { id:3 , data:{ name:"sample3",address:{ cat:"office"  } } },
 { id:4 , data:{ name:"sample4",address:{ cat:"office"  }  } }
 { id:5 , data:{ name:"sample5",address:{ cat:"home"  } } }
 { id:6 , data:{ name:"sample6",address:{ cat:"home"  }  } }
]



function filter( collection , value ,key ){
  //code 
}


let result = filter( data , "business" , [ "data","address","cat" ] )

console.log(result)

expected result is

{ id:1 , data:{ name:"sample1",address:{ cat:"business" } } },

3
  • You want to search for any of the of key, right? Mean to say, sometimes key may be id, name, address also? Commented May 30, 2018 at 3:28
  • No the key is the exact address of the value in the array. it could be also string or object you can modify it. Commented May 30, 2018 at 3:40
  • 1
    Very nice question Commented May 30, 2018 at 3:55

4 Answers 4

6

You can use filter to search for the data. Use reduce to construct the keys.

Note: filter returns an array of matched elements. If you prefer the first match only, you can use find

const data = [
  { id: 1, data: { name: "sample1", address:{ cat: "business" } } },
  { id: 2, data: { name: "sample2", address:{ cat: "office" } } },
  { id: 3, data: { name: "sample3", address:{ cat: "office" } } },
  { id: 4, data: { name: "sample4", address:{ cat: "office" } } },
  { id: 5, data: { name: "sample5", address:{ cat: "home" } } },
  { id: 6, data: { name: "sample6", address:{ cat: "home" } } }
]

const filter = (collection, keys, value) => 
  collection.filter(o => keys.reduce((c, v) => c[v] || {}, o) === value)
const result = filter(data, ["data", "address", "cat"], "business")

console.log(result)

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

3 Comments

Might help to make a note about returning an array instead of a single item
This is one am looking for thank you Eddie .. its very native .. no need lodash.. :)
Crazometer, you right. I noted it above. @JakeGarbo Happy to help :)
1
function filter( collection , value ,key ){
  const getNestedObjectValue = (nestedObject, propertyPath) => {
      return propertyPath.reduce((obj, key) =>
          (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObject);

  };
  return collection.filter( item => getNestedObjectValue(item, key) === value);
}

The filter function will return an array of matching object(s) when there is a match and an empty array when there is no match

let result = filter( data , "business" , [ "data","address","cat" ] );

console.log(result); // [{"id":1,"data":{"name":"sample1","address":{"cat":"business"}}}]

let result2 = filter( data , "office" , [ "data","address","cat" ] );

console.log(result2); //[{"id":2,"data":{"name":"sample2","address":{"cat":"office"}}},{"id":3,"data":{"name":"sample3","address":{"cat":"office"}}},{"id":4,"data":{"name":"sample4","address":{"cat":"office"}}}]

let result3 = filter( data , "vacation" , [ "data","address","cat" ] );

console.log(result2); // [] 

Comments

0

You can try below code.

Please comment if it doesn't satisfy your problem or if you want more functionality to be added in the code. I will update my answer.

function filter( collection , value ,key ){
     for(var obj of collection) {
           if(obj[key[0]][key[1]][key[2]] == value)
           { 
               return obj
           }
     }
     return null;
}

2 Comments

Thanks for the help bro but this answer cannot be dynamic .. for instance the key is only 1 or 2 .
Okay, can you please add 2-3 test cases with expected output? I will make it dynamic soon. Thanks.
0

Clean code using Underscore and ES6 arrow notation.

const equalTo = expected => actual => expected === actual;

function filterDeepValue(collection, value, path) {
    const criterion = _.compose(equalTo(value), _.property(path));
    return _.filter(collection, criterion);
}

const data = [
    {id: 1, data: {name: "sample1", address: {cat: "business"}}},
    {id: 2, data: {name: "sample2", address: {cat: "office"}}},
    {id: 3, data: {name: "sample3", address: {cat: "office"}}},
    {id: 4, data: {name: "sample4", address: {cat: "office"}}},
    {id: 5, data: {name: "sample5", address: {cat: "home"}}},
    {id: 6, data: {name: "sample6", address: {cat: "home"}}},
];

console.log(filterDeepValue(data, 'business', ['data', 'address', 'cat']));
<script src="https://underscorejs.org/underscore-umd-min.js"></script>

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.