根据其他属性从对象数组中提取属性

时间:2019-07-10 13:56:38

标签: javascript algorithm

我有对象数组,并希望基于另一个对象获取一些属性

假设

var lngs = [{id : 3 , label : 'a'} , {id : 2 , label : 'b' , {id : 4 , label : 'c'}];

现在我需要获取基于ID的标签数组

例如

getAttrs([4,3]);

function getAttrs(ids , arr)
{
   // as long as ids = [4,3] , it should return
   ["c","a"]
}

我尝试了这种算法,但是没有按预期工作

 langsFromIds(ids)
 {
   var rslt = [];
   var lngs = this.state.langs;
   for (var i = 0 ; i < lngs.length ; i++)
   {
     if (lngs[i].id == ids[i])
     {
       rslt.push(lngs[i].label);
     }
   }

   return rslt;
 }

因为它以这种方式运行(例如)

  

第一次迭代(i == 0)=> lngs [i] .id == 3 && ids [i] == 4(将不匹配)

     

第二次迭代(i == 1)=> lngs [i] .id == 2 && ids [i] == 3(不匹配)

     

以此类推..

因此它将返回空数组

4 个答案:

答案 0 :(得分:1)

首先过滤出正确的ID,然后提取所需的标签:

var lngs = [{id : 3 , label : 'a'} , {id : 2 , label : 'b'} , {id : 4 , label : 'c'}];

function langsFromIds(ids, langs)
{
  return langs.filter(lng => ids.indexOf(lng.id) > -1).map(lng => lng.label);
}

console.log(langsFromIds([4, 3], lngs));

答案 1 :(得分:1)

您可以使用filterfind来获取单个lng对象的列表...

var lngs = [{id:3,label:'a'},{id:2,label:'b'},{id:4,label:'c'}];

function lngsFromIds(ids) {
  return lngs.filter(x => ids.find(y => y == x.id));
}
console.log(lngsFromIds([3,4]));

然后使用map来获取label ...

var lngs = [{id:3,label:'a'},{id:2,label:'b'},{id:4,label:'c'}];

function labelsFromIds(ids) {
  return lngs.filter(x => ids.find(y => y == x.id)).map(z => z.label);
}
console.log(labelsFromIds([3,4]));

答案 2 :(得分:0)

这是我的主张:

var lngs = [{id : 3 , label : 'a'} , {id : 2 , label : 'b' }, {id : 4 , label : 'c'}];

var npq = getAttrs([4,3]);
console.log(npq);

function getAttrs(ids)
{
   var rslt = [];
   //var lngs = this.state.langs;
    for (var k = 0; k < ids.length; k++)
    {
        for (var i = 0 ; i < lngs.length ; i++)
        {
          if (lngs[i].id == ids[k])
          {
             rslt.push(lngs[i].label);
          }
        }
    }
   return rslt;
}

答案 3 :(得分:0)

  • 要回答您的问题,您正在将索引与索引匹配,因此无法获得理想的结果,因为id可以在ids中的任何位置找到。

  • 一种快速的解决方案是在ids上再次进行内部迭代,如果找到匹配项,则将它们添加到结果中。

var lngs = [{id:3,label:'a'},{id:2,label:'b'},{id:4,label:'c'}];

function langsFromIds(ids)
 {
   var rslt = [];
   for (var i = 0 ; i < lngs.length ; i++)
   {
     for(var j=0; j < ids.length;j++)
     {
      	if (lngs[i].id == ids[j])
     	{
       		rslt.push(lngs[i].label);
     	}	 
     }
   }

   return rslt;
 }

console.log(langsFromIds([3,4]));

  • 尽管上述解决方案有效,但它不可扩展,这意味着如果lngs的大小与ids一起变大,上述解决方案将花费大量时间来返回结果。换句话说,时间复杂度为O(n * m),其中nlngs的大小,而mids的大小。

  • 因此, if 的目标是一种有效的方法,您可以将ids中的set设为lngs,并检查{ {1}}。

var lngs = [{id:3,label:'a'},{id:2,label:'b'},{id:4,label:'c'}];

function lngsFromIds(ids) {
  var set = new Set(ids);
  return lngs.filter(x => set.has(x.id)).map(x => x.label);
}
console.log(lngsFromIds([3,4]));

  • 以上方法可以确定当前对象的idids中是否存在于平均O(1)时间上,从而使函数更快。时间复杂度将是O(n + m)时间,而O(m)n的空间要折衷,其中mstruct C { void window_size(GLFWwindow*, int, int); }; auto window_size_callback = [](GLFWwindow* window, int w, int h) { C c; c.window_size(window, w, h); }; // a non-capturing lambda can be converted to a function pointer // you can use a named function if you prefer glfwSetWindowSizeCallback(window, window_size_callback); 与前面提到的相同。