在嵌套数组中查找对象及其位置

时间:2018-10-12 06:12:32

标签: javascript

我从另一个问题中选取了以下示例。而且我能够识别物体。但是,我还需要找到该对象的位置。例如:

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

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

  }
]

如果要通过类别ID查找对象,可以使用以下内容:

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);
    }));
});

但是,我还需要知道对象在数组中的位置。例如,如果我们正在寻找Id = 100的对象,那么上面的代码将找到该对象,但是如何找到它是主数组中的第二个对象以及Categories数组中的第一个对象?

谢谢!

5 个答案:

答案 0 :(得分:3)

好吧,如果每个对象都是唯一的(仅属于其中一个类别),则可以简单地遍历所有对象。

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++;
});

答案 1 :(得分: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;
}

如果需要位置并且必须过滤对象的属性,则可以使用简单的for循环。在此示例中,您的结果是一个新对象的数组,因为该属性的值可能比1多。

我希望对您有帮助

答案 2 :(得分:0)

这是使用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))    // {}

答案 3 :(得分:0)

遍历数组并在找到匹配项的对象中设置索引

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);

答案 4 :(得分:0)

除了给出固定深度搜索的答案之外,您还可以通过检查嵌套结构的DECLARE @lang varchar(2) ='en', @hideInactiveCompany integer = 0 IF @hideInactiveCompany = 1 SELECT <all columns> FROM Config.BusinessUnit BU LEFT JOIN Config.Organization CO on BU.OrganizationId = CO.OrganizationId LEFT JOIN Config.ParentBusinessUnit PBU on BU.ParentBusinessUnitId = PBU.ParentBusinessUnitId WHERE BU.IsActive = 1 --the additional condition if @hideInactiveCompany=1 ORDER BY CASE WHEN @lang = 'cn' THEN BU.Lang END, CASE WHEN @lang = 'en' THEN BU.Lang END DESC, EntityName ELSE SELECT <all columns> FROM Config.BusinessUnit BU LEFT JOIN Config.Organization CO on BU.OrganizationId = CO.OrganizationId LEFT JOIN Config.ParentBusinessUnit PBU on BU.ParentBusinessUnitId = PBU.ParentBusinessUnitId ORDER BY CASE WHEN @lang = 'cn' THEN BU.Lang END, CASE WHEN @lang = 'en' THEN BU.Lang END DESC, EntityName 属性来采用递归方法。

Categories
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));