【问题标题】:How we can merge multidimensional array with JavaScript or underscore or lodash我们如何将多维数组与 JavaScript 或下划线或 lodash 合并
【发布时间】:2019-07-11 11:43:03
【问题描述】:

我们如何合并和加入这段代码的键值(javascript 或 undescore 或 lodash)。

数组数据:

[[
    {
      "Product": "Men's Cut and Sewn",
      "Monday": 13,
      "Tuesday": 1.29,
      "Thursday": 10,
      "Friday": 2,
      "Saturday": 2.1,
      "Sunday": 12
    },
    {
      "Product": "Men's Inner",
      "Monday": 10,
      "Tuesday": 1.29,
      "Wednesday ": 2.6,
      "Thursday": 4.9,
      "Friday": 2,
      "Saturday": 20,
      "Sunday": 12
    }
  ],
  [
    {
      "Product": "Men's Cut and Sewn",
      "Monday": 10,
      "Tuesday": 45,
      "Wednesday": 45,
      "Thursday": 23,
      "Friday": 2,
      "Saturday": 3,
      "Sunday": 2
    },
    {
      "Product": "Men's Inner",
      "Monday": 1,
      "Tuesday": 1,
      "Thursday": 34,
      "Friday": 5,
      "Saturday": 34,
      "Sunday": 34
    }
  ]]

预期数据:

[{
 {
      "Product": "Men's Cut and Sewn",
      "Monday": 23,
      "Tuesday": 2.58,
      "Wednesday": 45,
      "Thursday": 33,
      "Friday": 4,
      "Saturday": 5.1,
      "Sunday": 14
    },
    {
      "Product": "Men's Inner",
      "Monday": 11,
      "Tuesday": 2.29,
      "Wednesday ": 2.6,
      "Thursday": 38.9,
      "Friday": 7,
      "Saturday": 54,
      "Sunday": 46
    }
}] 

我尝试了这个 JavaScript 代码

var finalArr = [];
for (var i = 0; i < arr.length - 1; i++) {

  if (i < arr.length - 1 && finalArr.length > 0) {
    var arr1 = finalArr;
    var arr2 = arr[i]
  } else {
    var arr1 = arr[i];
    var arr2 = arr[i + 1];
  }

  for (let obj1 of arr1) {
    var sampleObj = {};

    for (let obj2 of arr2) {
      if (obj1.Product === obj2.Product) {
        sampleObj.Product = obj1.Product;
        for (let day in obj1) {
          if (day !== 'Product') {
            sampleObj[day] = parseInt(obj1[day] + obj2[day]);
          }
        }
      }
    }

    finalArr.push(sampleObj);
  }
}

它可以是 n 个数组,如果没有找到相同产品的某个数组也需要添加键(一个数组没有“星期一”键,但在第二个数组中具有相同产品的“星期一”键则需要加入两个星期一值)。

this.url = ['assets/sample-dataset.xlsx', 'assets/sheet2.xlsx'];

this.jsonData = XLSX.utils.sheet_to_json(worksheet, { raw: true });

两张表两个数组数据。无法将这些多个数组合并为一个数组。 jsonData 给定了两个带有上图的数组。需要合并成一个数组[[array1],[array2]]

【问题讨论】:

  • 如果您从“这就是我尝试过的”以及任何调试细节开始,这个问题就不会这么快就结束了,您将有机会获得帮助。否则,看起来您希望 Stackoverflow 成为免费的代码编写服务
  • 产品名称相同。 @RenéDatenschutz

标签: javascript underscore.js lodash


【解决方案1】:

您可以使用 lodash 通过_.flow() 创建管道函数。该函数将子数组展平为单个数组,按Product 对项目进行分组,然后将组对象映射回数组,并将每个组合并为单个对象:

const { flow, flatten, partialRight: pr, groupBy, map, mergeWith, isNumber } = _ // replace with imports in your code

const fn = flow(
  flatten, // convert to a single array,
  pr(groupBy, 'Product'), // convert to groups by with the product as key
  pr(map, group => mergeWith({}, ...group, (a, b) => _.isNumber(a) ? _.add(a, b) : undefined)) // combine the items of each group to a single item 
)

const arr = [[{Product:"Men's Cut and Sewn",Monday:13,Tuesday:1.29,Thursday:10,Friday:2,Saturday:2.1,Sunday:12},{Product:"Men's Inner",Monday:10,Tuesday:1.29,"Wednesday":2.6,Thursday:4.9,Friday:2,Saturday:20,Sunday:12}],[{Product:"Men's Cut and Sewn",Monday:10,Tuesday:45,Wednesday:45,Thursday:23,Friday:2,Saturday:3,Sunday:2},{Product:"Men's Inner",Monday:1,Tuesday:1,Thursday:34,Friday:5,Saturday:34,Sunday:34}]]

const result = fn(arr)


console.log(result)
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.14/lodash.js"&gt;&lt;/script&gt;

还有一个使用 lodash/fp 的更简洁的版本:

const { flow, flatten, groupBy, map, mergeAllWith, isNumber } = _ // replace with imports in your code

const fn = flow(
  flatten, // convert to a single array,
  groupBy('Product'), // convert to groups by with the product as key
  map(mergeAllWith((a, b) => _.isNumber(a) ? _.add(a, b) : undefined)) // combine the items of each group to a single item 
)

const arr = [[{Product:"Men's Cut and Sewn",Monday:13,Tuesday:1.29,Thursday:10,Friday:2,Saturday:2.1,Sunday:12},{Product:"Men's Inner",Monday:10,Tuesday:1.29,"Wednesday":2.6,Thursday:4.9,Friday:2,Saturday:20,Sunday:12}],[{Product:"Men's Cut and Sewn",Monday:10,Tuesday:45,Wednesday:45,Thursday:23,Friday:2,Saturday:3,Sunday:2},{Product:"Men's Inner",Monday:1,Tuesday:1,Thursday:34,Friday:5,Saturday:34,Sunday:34}]]

const result = fn(arr)


console.log(result)
&lt;script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'&gt;&lt;/script&gt;

【讨论】:

    【解决方案2】:

    您可以使用嵌套的forEach。最终目标是创建一个累加器对象,其中所有 Product 作为键,输出数组中需要的值作为它的值。创建一个defaultObj,将一周中的所有日期作为键,0 作为值。在嵌套数组循环中,destructuredays 键的Productrest 作为单独的对象。循环遍历days 的键并更新各个Product 的值

    const arr = [[{Product:"Men's Cut and Sewn",Monday:13,Tuesday:1.29,Thursday:10,Friday:2,Saturday:2.1,Sunday:12},{Product:"Men's Inner",Monday:10,Tuesday:1.29,"Wednesday":2.6,Thursday:4.9,Friday:2,Saturday:20,Sunday:12}],[{Product:"Men's Cut and Sewn",Monday:10,Tuesday:45,Wednesday:45,Thursday:23,Friday:2,Saturday:3,Sunday:2},{Product:"Men's Inner",Monday:1,Tuesday:1,Thursday:34,Friday:5,Saturday:34,Sunday:34}]],
        defaultObj = { Monday: 0, Tuesday: 0, Wednesday: 0, Thursday: 0, Friday: 0, Saturday: 0, Sunday: 0 },
        group = { };
    
    arr.forEach(inner => {
      inner.forEach(({ Product, ...days }) => {
        group[Product] = group[Product] || { Product, ...defaultObj };
        for (const key in days)
          group[Product][key] += days[key];
      })
    })
    
    console.log(Object.values(group))

    这就是group 对象的样子

    {
      "Men's Cut and Sewn": {
        "Product": "Men's Cut and Sewn",
        "Monday": 23,
        "Tuesday": 46.29,
        "Wednesday": 45,
        "Thursday": 33,
        "Friday": 4,
        "Saturday": 5.1,
        "Sunday": 14
      },
      "Men's Inner": {
        "Product": "Men's Inner",
        "Monday": 11,
        "Tuesday": 2.29,
        "Wednesday": 2.6,
        "Thursday": 38.9,
        "Friday": 7,
        "Saturday": 54,
        "Sunday": 46
      }
    }
    

    你可以使用Object.values()来获取这个对象的值作为一个数组


    上面的代码将为一周中的所有天添加一个值。假设Men's Cut and Sewn 产品在任何一个数组中都没有Monday 的值,并且您不希望在输出中使用带有0 作为值的Monday 键。除了使用defaultObj,您可以添加一个额外的if-else 来检查是否已经添加了这一天。

    const arr = [[{Product:"Men's Cut and Sewn",Monday:13,Tuesday:1.29,Thursday:10,Friday:2,Saturday:2.1,Sunday:12},{Product:"Men's Inner",Monday:10,Tuesday:1.29,"Wednesday":2.6,Thursday:4.9,Friday:2,Saturday:20,Sunday:12}],[{Product:"Men's Cut and Sewn",Monday:10,Tuesday:45,Wednesday:45,Thursday:23,Friday:2,Saturday:3,Sunday:2},{Product:"Men's Inner",Monday:1,Tuesday:1,Thursday:34,Friday:5,Saturday:34,Sunday:34}]],
        group = { };
    
    arr.forEach(inner => {
      inner.forEach(({ Product, ...days }) => {
        group[Product] = group[Product] || { Product };
        for (const key in days) {
          if(group[Product][key])
            group[Product][key] += days[key];
          else 
            group[Product][key] = days[key];
        }
      })
    })
    
    console.log(Object.values(group))

    【讨论】:

      【解决方案3】:

      const arr = [[{Product:"Men's Cut and Sewn",Monday:13,Tuesday:1.29,Thursday:10,Friday:2,Saturday:2.1,Sunday:12},{Product:"Men's Inner",Monday:10,Tuesday:1.29,"Wednesday":2.6,Thursday:4.9,Friday:2,Saturday:20,Sunday:12}],[{Product:"Men's Cut and Sewn",Monday:10,Tuesday:45,Wednesday:45,Thursday:23,Friday:2,Saturday:3,Sunday:2},{Product:"Men's Inner",Monday:1,Tuesday:1,Thursday:34,Friday:5,Saturday:34,Sunday:34}]],
          group = { };
      
      arr.forEach(inner => {
        inner.forEach(({ Product, ...days }) => {
          group[Product] = group[Product] || { Product };
          for (const key in days) {
            if(group[Product][key])
              group[Product][key] += days[key];
            else 
              group[Product][key] = days[key];
          }
        })
      })
      
      console.log(Object.values(group))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-15
        • 1970-01-01
        • 2021-01-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多