0

I've been working on creating an omit function with a source and keys parameter, that checks for keys within the source, and if they are found, those properties are omitted from the source, then create a new object literal with the remaining key/value pairs within the source. So far, I've been unsuccessful, and only have been able to create a function that does the opposite of creating an object with the keys found within the source. Can anyone help figure out what I'm missing? It would be very appreciated!

function omit(source, keys) {
  var includedSource = {};
  for (var key in source) {
    for (var i = 0; i < keys.length; i++) {
      if (keys[i] !== key) {
        includedSource[key] = source[key];
        console.log('source[keys[i]]:', source[keys[i]]);
        console.log('includedSource:', includedSource);
      }
    }
  }
  return includedSource;
}

  function omit(source, keys) {
    var includedSource = {};
    for (var key in source) {
      for (var i = 0; i < keys.length; i++) {
        if (keys[i] === key) {
          includedSource[key] = source[key];
          console.log('source[keys[i]]:', source[keys[i]]);
          console.log('includedSource:', includedSource);
          }
        }
     }
     return includedSource;
   }
JB49er
  • 15
  • 3
  • 1
    Your function doesn't check if it's found, it just checks whether it's not equivalent to *any* of the keys. Which means that as soon as you pass in two different `keys`, it will copy all keys from the `source`. – Bergi Jan 15 '22 at 19:08
  • Bergi, I see what you're saying. That's where I was having issues with, figuring out how to check if any properties of source is located within keys, then returning the result into a new object. Everyone's input was very helpful! Thanks all! – JB49er Jan 15 '22 at 20:18

5 Answers5

2

Here is a simple implementation with flat object. Im not sure how would keys be declared if your object might be nested, and you would expect to extract some of N level of nested value/keys

const obj = {
  A: 1,
  B: 2,
  C: 3,
  D: 4
};

function omit(data, keys) {
  let result = {};

  for (let key in data) {
    if (keys.includes(key)) continue;

    result[key] = data[key];
  }

  return result;
}

console.log(omit(obj, ["A", "D"])) // {B: 2, C: 3}
Eduard
  • 1,319
  • 6
  • 12
1

You could destructure and rest for a new object.

function omit(object, keys) {
    let _; // prevent to be global
    for (const key of keys) ({ [key]: _, ...object } = object);
    return object;
}

console.log(omit({ a: 1, b: 2, c: 3, d: 4 }, ['b', 'c']));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

One approach is use Object.entries() and filter the entries out that have the unwanted keys then use Object.fromEntries() to create the new object from the filtered entries

const omit = (data, keys) => {
  return Object.fromEntries(
    Object.entries(data).filter(([k]) => !keys.includes(k))
  )
}


console.log(omit({ a:1,b:2,c:3,d:4}, ['a', 'b']))
charlietfl
  • 170,828
  • 13
  • 121
  • 150
1

Converting to entries with Object.entries and Object.fromEntries and then filtering said entries with <Array>.filter might work nicely:

const omit = (obj, keys) => Object.fromEntries(Object.entries(obj).filter(a=>!keys.includes(a[0])));
skara9
  • 4,042
  • 1
  • 6
  • 21
0

The problem with your solution is that, keys[i + 1] could be equal to key, even though keys[i] does not.

To correct your code, apply following change.

function omit(source, keys) {
  var includedSource = {};
  for (var key in source) {
    if(!keys.includes(key)) { // <--- Change this
       includedSource[key] = source[key];
       console.log('source[keys[i]]:', source[keys[i]]);
       console.log('includedSource:', includedSource);
    }
  }
  return includedSource;
}

Another approach, just for fun.

function omit(source, keys) {
    return Object.keys(source).reduce((acc, curr) => {
        return {...acc, ...(keys.includes(curr) ? {} : {[curr]: source[curr]})}
    }, {})
}
Parnab Sanyal
  • 749
  • 5
  • 19