【问题标题】:Normalize/Flatten a JS array using LoDash or similar?使用 LoDash 或类似方法规范化/展平 JS 数组?
【发布时间】:2016-03-17 16:00:52
【问题描述】:

我需要能够规范化 javascript 对象或将其展平,我希望能够用 lodash 做一些事情,但我不知所措。我尝试编写自己的转换器,但它似乎过于复杂,而且我认为 lodash 可以做这样的事情。

我正在放置我拥有的原始数组,它有 3 个带有子数组的项目。 (见下文)

这是我所期望的(创建我的新对象),因此所有内容都被展平并添加到“名称”中(请参见下面的 testProduct1 和 testProduct2),如果没有可用的颜色、位置,那么名称就是原始名称(请参阅下面的 testProduct3)。

{
   name: ‘testProduct1 RED NewYork’
},
{
   name: ‘testProduct1 RED London’
},
{
   name: ‘testProduct1 YELLOW NewYork’
},
{
   name: ‘testProduct1 YELLOW London’
},
{
   name: ‘testProduct2 WHITE NewYork’
},
{
   name: ‘testProduct2 WHITE London’
},
{
   name: ‘testProduct3’
}

这里是原始数组的例子

{
    name: ‘testProduct1’,
    colors: [
       ‘RED’,
       ‘YELLOW’
    ],
    locations: [
       ‘New York’,
       ‘London’
    ]
},
{
    name: ‘testProduct2’,
    colors: [
       ‘WHITE’
    ],
    locations: [
       ‘New York’,
       ‘London’
    ]
},
{
    name: ‘testProduct3’,
}

【问题讨论】:

  • 只是出于好奇,这不是de规范化吗?
  • 弯引号不能很好地工作。

标签: javascript lodash


【解决方案1】:

这是一个纯 Javascript 的解决方案。

var data = [{ name: 'testProduct1', colors: ['RED', 'YELLOW'], locations: ['New York', 'London'] }, { name: 'testProduct2', colors: ['WHITE'], locations: ['New York', 'London'] }, { name: 'testProduct3', }],
    flat = function (array) {
        var order = ['colors', 'locations'],
        r = [];
        array.forEach(function (a) {
            function getParts(parts) {
                if (parts.length >= order.length) {
                    parts.unshift(a.name);
                    r.push({ name: parts.filter(Boolean).join(' ') });
                    return;
                }
                (a[order[parts.length]] || ['']).forEach(function (b) {
                    getParts(parts.concat(b));
                });
            }
            getParts([]);
        });
        return r;
    }(data);

document.write('<pre>' + JSON.stringify(flat, 0, 4) + '</pre>');

【讨论】:

    【解决方案2】:

    我猜你想要map

    list.map((element) => {
        return {
            name: [element.name].concat(element.colors, element.locations).join(' ')
        };
    });
    

    【讨论】:

    • 我不会使用粗箭头函数来回答您的问题。大多数浏览器还不支持它们
    • 我认为使用粗箭头函数很好。 Chrome、Firefox 和 Edge 原生支持它们,当然还有任何转译器。如果用户在他们不在的环境中工作,他可以​​做一个微不足道的重写。更基本的问题是这个答案不起作用。
    • @acbabis 顺便说一句,正确的术语是“箭头函数”。
    • @torazaburo 实际上,两者都可以接受。来自MDN documentation:“一个箭头函数表达式(也称为胖箭头函数)有...”
    • @Acbabis 不是真的。该规范使用术语“箭头函数”。 MDN 页面中的“也称为”应理解为“基于早期的,现在已弃用的用法,也通俗地称为胖箭头函数......”。
    【解决方案3】:
    var resultArr = inArr.reduce((initArr, cur) =>
      {
        if (cur.colors && cur.locations)
        {
          cur.colors.forEach(col => 
          cur.locations.forEach(loc =>
            initArr.push({ name: cur.name + ' ' + col + ' ' + loc })));
        }  
        else
        {
          initArr.push({ name: cur.name });
        }
    
        return initArr;
      }, [] /* Passed as initArr */);
    

    更简洁

    var resultArr = inArr.reduce((initArr, cur) =>
      {
        for (let col of cur.colors || ['']) 
          for (let loc of cur.locations || [''])
            initArr.push({ name: (cur.name + ' ' + col + ' ' + loc).trim() });
        return initArr;
      }, [] /* Passed as initArr */);
    

    【讨论】:

      【解决方案4】:

      编写一组基本循环可能更容易:

      var result = [];
      for (let i = 0; i < arr.length; i++) {
        let colors = arr[i].colors || [];
        for (let j = 0; j < colors.length; j++) {
          let locations = arr[i].locations || [];
          for (let k = 0; k < locations.length; k++) {
            result.push({name: arr[i].name + ' ' + colors[j] + ' ' + locations[k]]});
          ]
        }
      }
      

      如果你真的想用函数式风格写这个,那么一个想法是:

      [].concat(...arr.map(
        elt => (elt.colors || []).map(
          color => (elt.locations || []).map(
            location => ({name: elt.name + ' ' + color + ' ' + location})))))
      

      【讨论】:

      • 这不起作用,因为列表中的第三项没有colors 属性或locations 属性。
      猜你喜欢
      • 1970-01-01
      • 2015-01-25
      • 2021-12-11
      • 1970-01-01
      • 2012-10-19
      • 2022-01-08
      • 1970-01-01
      • 2021-03-22
      • 2020-09-05
      相关资源
      最近更新 更多