1

I've taken the following sample from a different question. And I am able to identify the object. But I also need to find our the position of that object. For example:

var arr = [{
    Id: 1,
    Categories: [{
        Id: 1
      },
      {
        Id: 2
      },
    ]

  },
  {
    Id: 2,
    Categories: [{
        Id: 100
      },
      {
        Id: 200
      },
    ]

  }
]

If I want to find the object by the Id of the Categories, I can use the following:

var matches = [];
var needle = 100; // what to look for

arr.forEach(function(e) {
    matches = matches.concat(e.Categories.filter(function(c) {
        return (c.Id === needle);
    }));
});

However, I also need to know the position of the object in the array. For example, if we are looking for object with Id = 100, then the above code will find the object, but how do I find that it's the second object in the main array, and the first object in the Categories array?

Thanks!

4
  • 1
    Exactly what sort of output are you looking for? Something like { idIndex: 1, catIndex: 0 } or what? Commented Oct 12, 2018 at 6:14
  • What is ar matches? Commented Oct 12, 2018 at 6:14
  • I am looking for arrIndex: 0. So basically I need to know that it's position is 1 in main array, and that within category, it's at position 0. Commented Oct 12, 2018 at 6:15
  • Sorry, I corrected the code mistakes. Commented Oct 12, 2018 at 6:17

5 Answers 5

3

Well, if every object is unique (only in one of the categories), you can simply iterate over everything.

var arr = [{
    Id: 1,
    Categories: [{Id: 1},{Id: 2}]
  },
  {
    Id: 2,
    Categories: [{Id: 100},{Id: 200}]
  }
];

var needle = 100;

var i = 0;
var j = 0;

arr.forEach(function(c) {
  c.Categories.forEach(function(e) {
    if(e.Id === needle) {
      console.log("Entry is in position " + i + " of the categories and in position " + j + " in its category.");
    }
    j++;
  });
  j = 0;
  i++;
});

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

Comments

0
function findInArray(needle /*object*/, haystack /*array of object*/){
  let out = [];
  for(let i = 0; i < haystack.lenght; i++) {
    if(haystack[i].property == needle.property) {
      out = {pos: i, obj: haystack[i]};
    }
  }
  return out;
}

if you need the position and have to filter over an property of the object you can use a simple for loop. in this sample your result is an array of new object because there can be more mathches than 1 on the value of the property.

i hope it helps

Comments

0

Iterate over the array and set index in object where match found

var categoryGroups = [{
        Id : 1,
        Categories : [{
                Id : 1
            }, {
                Id : 2
            },
        ]

    }, {
        Id : 2,
        Categories : [{
                Id : 100
            }, {
                Id : 200
            },
        ]

    }
]

var filterVal = [];
var needle = 100;
for (var i = 0; i < categoryGroups.length; i++) {

    var subCategory = categoryGroups[i]['Categories'];
    for (var j = 0; j < subCategory.length; j++) {

        if (subCategory[j]['Id'] == findId) {
            filterVal.push({
                catIndex : i,
                subCatIndex : j,
                id : needle
            });
        }

    }
}

console.log(filterVal);

Comments

0

Here is solution using reduce:

var arr = [{ Id: 1, Categories: [{ Id: 1 }, { Id: 2 }, ] }, { Id: 2, Categories: [{ Id: 100 }, { Id: 200 }, ] } ]

const findPositions = (id) => arr.reduce((r,c,i) => { 
   let indx = c.Categories.findIndex(({Id}) => Id == id) 
   return indx >=0 ? {mainIndex: i, categoryIndex: indx} : r
}, {})

console.log(findPositions(100))  // {mainIndex: 1, categoryIndex: 0}
console.log(findPositions(1))    // {mainIndex: 0, categoryIndex: 0}
console.log(findPositions(200))  // {mainIndex: 1, categoryIndex: 1}
console.log(findPositions(0))    // {}

Comments

0

Beside the given answers with fixt depth searh, you could take an recursive approach by checking the Categories property for nested structures.

function getPath(array, target) {
    var path;
    array.some(({ Id, Categories = [] }) => {
        var temp;
        if (Id === target) {
            path = [Id];
            return true;
        }
        temp = getPath(Categories, target);
        if (temp) {
            path = [Id, ...temp];
            return true;
        }
    });
    return path;
}

var array = [{ Id: 1, Categories: [{ Id: 1 }, { Id: 2 },] }, { Id: 2, Categories: [{ Id: 100 }, { Id: 200 }] }];

console.log(getPath(array, 100));
.as-console-wrapper { max-height: 100% !important; top: 0; }

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.