Jimi
Jimi

Reputation: 1897

es6 filter JSON returns undefined, filter object does not

I have a filter function that is returning undefined only when JSON is passed into it. I'd like to use this function to filter objects, JSON or anything really. Whats the best way to make this work on both objects and JSON?

let a = [{
  "employees": {
    "employee": [{
      "id": "1",
      "firstName": "Tom",
      "lastName": "Cruise"
    }, {
      "id": "2",
      "firstName": "Maria",
      "lastName": "Sharapova"
    }, {
      "id": "3",
      "firstName": "James",
      "lastName": "Bond"
    }]
  }
}];

var b = [{
  name: '',
  grade: 'x'
}, {
  name: 'yaya',
  grade: 'x'
}, {
  name: 'x',
  frade: 'd'
}, {
  name: 'a',
  grade: 'b'
}];

function findIt(arr, searchKey) {
  return arr.filter(obj => Object.keys(obj).some(key => obj[key].includes(searchKey)));
}

if (a) {
  console.log("I found: ", findIt(a, "James")); // breaks
}

if (b) {
  console.log("I found: ", findIt(b, "yaya")); // works fine
}

Upvotes: 1

Views: 1410

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386550

You need a reference to the inner array for searching.

findIt(a[0].employees.employee, "James"));
//      ^^^^^^^^^^^^^^^^^^^^^^

let a = [{ employees: { employee: [{ id: "1", firstName: "Tom", lastName: "Cruise" }, { id: "2", firstName: "Maria", lastName: "Sharapova" }, { id: "3", firstName: "James", lastName: "Bond" }] } }];
var b = [{ name: '', grade: 'x' }, { name: 'yaya', grade: 'x' }, { name: 'x', frade: 'd' }, { name: 'a', grade: 'b' }];

function findIt(arr, searchKey) {
    return arr.filter(obj => Object.keys(obj).some(key => obj[key].includes(searchKey)));
}

console.log(findIt(a[0].employees.employee, "James"));
console.log(findIt(b, "yaya"));

For a deeper find, you could use an recursive approach.

function findIt(object, search) {
    function find(k) {
        if (object[k] === search) {
            return result = object;
        }
        return result = findIt(object[k], search);
    }

    var result;
    if (object && typeof object === 'object') {
        Object.keys(object).some(find);
    }
    return result;
}


var a = [{ employees: { employee: [{ id: "1", firstName: "Tom", lastName: "Cruise" }, { id: "2", firstName: "Maria", lastName: "Sharapova" }, { id: "3", firstName: "James", lastName: "Bond" }] } }],
    b = [{ name: '', grade: 'x' }, { name: 'yaya', grade: 'x' }, { name: 'x', frade: 'd' }, { name: 'a', grade: 'b' }];

console.log(findIt(a, "James"));
console.log(findIt(b, "yaya"));
console.log(findIt(a, "foo"));   // undefined
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 2

Rajesh
Rajesh

Reputation: 24915

You can try to do a string search.

Logic

  • Create a copy of object but as string using JSON.stringify
  • Create a regex that searches for a pattern :<something>SearchValue.
  • Test object string with this regex and return it in filter

let a = [{ employees: { employee: [{ id: "1", firstName: "Tom", lastName: "Cruise" }, { id: "2", firstName: "Maria", lastName: "Sharapova" }, { id: "3", firstName: "James", lastName: "Bond" }] } }];
var b = [{ name: '', grade: 'x' }, { name: 'yaya', grade: 'x' }, { name: 'x', frade: 'd' }, { name: 'a', grade: 'b' }];


function findIt(arr, searchKey) {
  let reg = new RegExp(':(.*?)' + searchKey, 'g');
  return arr.filter(obj => reg.test(JSON.stringify(obj)));
}

console.log("I found: ", findIt(a, "James")); // breaks

console.log("I found: ", findIt(a[0].employees.employee, "James")); // breaks

console.log("I found: ", findIt(b, "yaya")); // works fine

Upvotes: 0

Related Questions