-1

I have a test array and a test object. I want to compare each element of test array with test object, but only those elements which are after the test object in the test array.

I have done it via the following example. Do we have any elegant way to do the same.

let testArray = [{ id: xx, name: 'C' },
    { id: xy, name: 'B' },
    { id: yz, name: 'C' },
    { id: ab, name: 'D' },
    { id: bc, name: 'E' },
    { id: cd, name: 'C' },
    { id: ce, name: 'E' },
    { id: ef, name: 'C' }];

let testObj = { id: 3, name: 'C' };

for (let i = testArray.indexOf(testObj) + 1; i < testArray.length; i++) {
  if (testObj.name === testArray[i].name) {
    console.log(testArray[i].id); // expected - object with id : cd and ef
    // if I change test object to { id: cd, name: 'C' } then answer should be object with id : ef
  }
}
kandarp
  • 991
  • 1
  • 14
  • 35
  • [How to determine equality for two JavaScript objects?](https://stackoverflow.com/questions/201183/how-to-determine-equality-for-two-javascript-objects) – Andreas Feb 11 '20 at 14:01
  • I'm a bit confused by your expected result. Why does `{ id: 3, name: 'C' }` return objects with `id: 6` and `id: 7`, but `{ id: 6, name: 'C' }` returns `id: 7`? – Tyler Roper Feb 11 '20 at 14:05
  • ^ If you're looking for "objects with the same name, with IDs higher than the given ID", the results should be `id: 6` and `id: 8`. For `{ id: 6, name: 'C' }`, i'd expect the result to be `id: 8`. But also - what happens if the suggested object isn't found? Is the passed-in object only compared on name, or ID too? – Tyler Roper Feb 11 '20 at 14:13
  • I am looking for an object with a same name but after the place of that object in the array. this is not about id at all. – kandarp Feb 11 '20 at 14:15
  • @kandarp The confusion was that prior to your edit, you had used `id: 7` as a return value instead of `id: 8`. The latest edit seems to correct that, but the IDs no longer match the object you're trying to find (nor are they valid javascript). – Tyler Roper Feb 11 '20 at 14:24

3 Answers3

1

You can do this way:

testArray.filter(i => i.id > testObj.id).forEach(i => console.log(i))

Just one line for filter and show all itens filtered.

Gabriel Willemann
  • 1,871
  • 1
  • 6
  • 11
  • that's a nice one – messerbill Feb 11 '20 at 14:04
  • 3
    You're assuming the array is sorted by ids in ascending order. – mbojko Feb 11 '20 at 14:05
  • 1
    The array can sort any way (asc or desc). It will work. – Gabriel Willemann Feb 11 '20 at 14:07
  • 1
    @mbojko, I could be wrong but I think regardless of order, the filter function will remove the IDs less than or equal to the testObj.id. – Dillan Wilding Feb 11 '20 at 14:08
  • OP says that for `id: 3`, the result should be objects with `id: 6` and `id: 7`. The result of this code would also log objects `id: 4`, `id: 5`, and `id: 8`. OP also seems to be doing an equality check on the `name` property. I believe the question isn't clear on its expectations, and therefore isn't in an answerable state. – Tyler Roper Feb 11 '20 at 14:09
  • @TylerRoper, yeah I'm honestly a little unclear on what OP is looking for but you could add `&& i.name === testObj.name` to the filter and only get "matches" after the testObj. – Dillan Wilding Feb 11 '20 at 14:11
  • I think you all miss-understood with id, I don't want to compare id of the object. I wanted to ask about the index of that object in the array. – kandarp Feb 11 '20 at 14:13
  • It is, even heading itself clarify the requirement. Can you please closely look to for loop that I used. I wanted to have all the element of same name from the array, which are coming after test-object. – kandarp Feb 11 '20 at 14:18
0

The following soluce will look for the index where the id is encountered, and then loop on the target array from the position.

Elegant way is highly subjective thought. We will all give you alternative syntax. Apply the one that is the most suitiable to your needs and that match your general coding style.

const testArray = [{
    id: 1,
    name: 'C',
  },
  {
    id: 2,
    name: 'B',
  },
  {
    id: 3,
    name: 'C',
  },
  {
    id: 4,
    name: 'D',
  },
  {
    id: 5,
    name: 'E',
  },
  {
    id: 6,
    name: 'C',
  },
  {
    id: 7,
    name: 'E',
  },
  {
    id: 8,
    name: 'C',
  },
];

const testObj = {
  id: 3,
  name: 'C',
};

// Find where to start
const pos = testArray.findIndex(x => x.id === testObj.id);

// Cut the array where you want to start looking and loop on it
testArray.slice(pos).forEach(({
  id,
  name,
}) => {
  if (name === testObj.name) {
    console.log(id);
  }
});
Orelsanpls
  • 22,456
  • 6
  • 42
  • 69
0

Use .findIndex() to find the correct object in the array.

Capture only items after that object by using slice(index+1).

Finally, .filter() to get objects with matching name values.

let testArray = [{ id: 1, name: 'C' },{ id: 2, name: 'B' },{ id: 3, name: 'C' },{ id: 4, name: 'D' },{ id: 5, name: 'E' },{ id: 6, name: 'C' },{ id: 7, name: 'E' },{ id: 8, name: 'C' }];
let testObj = { id: 3, name: 'C' };

const getItemsAfterObj = (arr, obj) => {
  const idx = arr.findIndex(o => o.id === obj.id && o.name === obj.name);
  if (idx === -1) throw "Object not found in array.";
  return arr.slice(idx+1).filter(o => o.name === obj.name);
};

const items = getItemsAfterObj(testArray,testObj);
console.log(items);
Tyler Roper
  • 21,445
  • 6
  • 33
  • 56