将包含对象的三维数组展平为二维数组,通过其参数去除重复对象。

5

我有一个包含对象的3D数组:

[
    [{ id: 1 }, { id: 2 }],
    [{ id: 3 }],
    [{ id: 3 }, { id: 4 }]
]

如何将其展平,包括删除重复的id参数?
[{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]

我认为使用下划线可能会对此有所帮助。
5个回答

3
var a = [
    [{ id: 1 }, { id: 2 }],
    [{ id: 3 }],
    [{ id: 3 }, { id: 4 }]
];

var flattened = _(a).flatten().uniq('id').value();

当然,您需要将lodash包含在您的网页中。


很好,lodash在uniq中有获取属性的快捷方式! - Cymen
下划线也可以做到这一点。 - Gruff Bunny

2
您可以这样使用 _.flatten_.uniq

var data = [
    [{ id: 1 }, { id: 2 }],
    [{ id: 3 }],
    [{ id: 3 }, { id: 4 }]
];

var result = _.uniq(_.flatten(data), function (el) {
    return el.id;
});

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>


2
你可以使用 Underscore 中的 flattenunique 来完成这个任务。但是,当你使用多个 Underscore 操作时,考虑使用 underscore 链式调用 以及 chainvalue 是一个不错的选择。
var data = [
    [{ id: 1 }, { id: 2 }],
    [{ id: 3 }],
    [{ id: 3 }, { id: 4 }]
];

var result = _.chain(data)
                  .flatten()
                  .uniq(function(o) {
                      return o.id;
                   })
                  .value();

console.log('result', result);

JSFiddle: http://jsfiddle.net/0udLde0s/3/ 更短的Underscore.js版本:
如果您使用最近版本的Underscore.js(我尝试了当前版本1.8.3),您可以使用.uniq('id'),使其更加简短:
var result = _.chain(data)
                  .flatten()
                  .uniq('id')
                  .value();

你可以在调用uniq函数时使用字符串'id'来替换函数。例如:.uniq('id') - Gruff Bunny
@GruffBunny 哦,你说得对,在underscorejs的当前版本中,.uniq('id')是可以工作的,但在我在JSFiddle上使用的旧版本(1.5)中不行。 - Cymen

0

你不需要任何库来完成这个,它非常简单:

function flatten(arr)
{
  var map = {};
  var flatArray = [];
  function pushToMap(o) {
    if(map[o.id])
      return;
  
    map[o.id] = true;
    flatArray.push(o);
  }
  function arrRecurse(a) {
    if(a.length === undefined)
      pushToMap(a);
    else {
      a.forEach(function(i) {
        arrRecurse(i);
      });
    }
  }

  arrRecurse(arr);
  return flatArray;
}

var _3dArray = [
    [{ id: 1 }, { id: 2 }],
    [{ id: 3 }],
    [{ id: 3 }, { id: 4 }]
];

alert(JSON.stringify(flatten(_3dArray)));


不错的非库解决方案,但有时候使用库会更好,特别是当它能让你的代码更清晰、更易读或更易于维护时。我们不能总是避免使用第三方解决方案,这就是为什么几乎每个页面都至少包含 jQuery 的原因。 - itachi
还有一件事,当检查“undefined”时,请这样做:if (typeof a === 'undefined') {...}if (a === undefined)将抛出异常。 - itachi
@itachi - 你说得没错,但是没有人提到网页。如今,Node是一个领先的平台。即使考虑客户端网页,在加载任何库时都有其成本(异步请求、加载、解析...),这取决于所需的复杂性。 - Amit
1
@itachi - 关于使用undefined,你是错的。a.length不会抛出异常 - 不需要使用typeof - Amit
你说得对。我的大脑没有捕捉到NotEnoughCoffee异常。 - itachi

0

没有库,只有本地JS:

var ar = [
  [{ id: 1 }, { id: 2 }],
  [{ id: 3 }],
  [{ id: 3 }, { id: 4 }]
];

//start
var output = [];
for (var x = 0, al = {}; x < ar.length; x++)
  for (var y = 0, t = ar[x][y]; y < ar[x].length; y++, t = ar[x][y])
      al[t.id] = (!al[t.id]) ? output.push(t) : 1;
//end

document.body.innerHTML += JSON.stringify(output);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接