【问题标题】:How to loop over a an array that is already inside a map function without duplicating the contents如何在不复制内容的情况下遍历已经在 map 函数中的数组
【发布时间】:2021-03-26 09:18:14
【问题描述】:

我有以下代码和以下数组。我想遍历它们并提取一些数据,然后将它们放入最终数组中。我能够做到这一点,但内容是重复的。我尝试阅读有关 reduce 的内容,但不太了解它,并且不确定它是否是正确的解决方案。我还设置了一个 jsfiddle

https://jsfiddle.net/anders_kitson/Lcqn6fgd/

var lineItems = [{
    id: 'li_1HyhAZHk5l44uIELgsMWqHqB',
    object: 'item',
    amount_subtotal: 7500,
    amount_total: 7500,
    currency: 'cad',
    description: 'The Spencer',
    price: [Object],
    quantity: 1
  },
  {
    id: 'li_1HyhAZHk5l44uIELeNUsiZPu',
    object: 'item',
    amount_subtotal: 7500,
    amount_total: 7500,
    currency: 'cad',
    description: 'The Gertie',
    price: [Object],
    quantity: 1
  }
]

var arr = [{
    id: 'prod_IS1wY1JvSv2CJg',
    object: 'product',
    active: true,
    attributes: [],
    created: 1606248785,
    description: 'Shelf Set',
    images: [
      'https://files.stripe.com/links/fl_test_raNEqk9ZhzX3WdQsnvXX4gFq'
    ],
    livemode: false,
    metadata: {},
    name: 'The Spencer',
    statement_descriptor: null,
    type: 'service',
    unit_label: null,
    updated: 1606248785
  },
  {
    id: 'prod_IS299dMnC13Ezo',
    object: 'product',
    active: true,
    attributes: [],
    created: 1606249543,
    description: 'Shelf Set',
    images: [
      'https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe'
    ],
    livemode: false,
    metadata: {},
    name: 'The Gertie',
    statement_descriptor: null,
    type: 'service',
    unit_label: null,
    updated: 1606249543
  }
];

let productArr = [];

arr.map((item) => {
  lineItems.map((line) => {
    productArr.push({
      image: item.images[0],
      name: item.name,
      price: line.amount_total,
    });
  });
});


console.log(productArr);

这是我得到的输出,你可以看到数组重复了这些值,我知道我是这样编码的,只是不知道如何修复它。

[{
  image: "https://files.stripe.com/links/fl_test_raNEqk9ZhzX3WdQsnvXX4gFq",
  name: "The Spencer",
  price: 7500
}, {
  image: "https://files.stripe.com/links/fl_test_raNEqk9ZhzX3WdQsnvXX4gFq",
  name: "The Spencer",
  price: 7500
}, {
  image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
  name: "The Gertie",
  price: 7500
}, {
  image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
  name: "The Gertie",
  price: 7500
}]

为了更清楚,这是我想要的输出

[{
      image: "https://files.stripe.com/links/fl_test_raNEqk9ZhzX3WdQsnvXX4gFq",
      name: "The Spencer",
      price: 7500
    }, {
      image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
      name: "The Gertie",
      price: 7500
    }, 
]

我已经在 cmets 中尝试了以下建议

let b

arr.map((item) => {
  b = lineItems.map((line) => {
    return {
      image: item.images[0],
      name: item.name,
      price: line.amount_total,
    };
  });
});

但它会返回相同的两次

[{
  image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
  name: "The Gertie",
  price: 7500
}, {
  image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
  name: "The Gertie",
  price: 7500
}]

【问题讨论】:

  • map 返回一个数组。使用它而不是 pushing 到一个新数组。
  • 第一张地图中的arr是什么?
  • 我从代码中生成的数组中获取了数组。我实际上正在运行一个对 arr 输出进行条带化的请求并运行另一个对 lineItems 进行条带化的请求,这就是为什么有单独的数组
  • @HereticMonkey 如果 map 返回一个数组,我如何将我需要的所有数据作为一个对象在其中获取,如我的输出所示?
  • 从传递给map的函数中返回对象。我强烈建议查看MDN's documentation on map

标签: javascript reduce array.prototype.map


【解决方案1】:

虽然没有直接在您的问题中表达,但您似乎希望在 javascript 中加入。我看到的与两者相关的唯一内容是产品中的“名称”和订单项中的“描述”。所以做一个循环加入。

以下是一些使用您的示例的示例代码,但仅精简到相关内容:

var lineItems =  [
    { amount_total: 7500, description: 'The Spencer' },
    { amount_total: 7500, description: 'The Gertie' }
  ]
  
var arr = [
  { images: ['Spencer Image 1'], name: 'The Spencer' },
  { images: ['Gertie Image 1'], name: 'The Gertie' }
]


let joined = arr
  .flatMap(a => lineItems.map(li => ({a, li})))
  .filter(obj => obj.a.name == obj.li.description)
  .map(obj => ({
    image: obj.a.images[0],
    name: obj.a.name,
    price: obj.li.amount_total
  }));

console.log(joined);
    

作为循环连接,它可能没有那么高效。做一个哈希连接有点复杂。你可以看一下我开发项目的源代码 fluent-data,或者如果你可以按照文档直接使用它甚至可能对你有用。

【讨论】:

  • Clippy +1,我什至没有继续阅读 :-)
【解决方案2】:

如果您知道两个数组的长度和顺序相同,您可以使用单个 map 调用并通过索引引用您的第二个 lineItems 数组

const output = arr.map((o, i) => ({
  name: o.name, 
  image: o.images[0], 
  price: lineItems[i].amount_total}
));

或使用find() 检索相关对象。

const outputUsingFind = arr.map(o => {
    const lineItem = lineItems.find(item => item.description === o.name);
    // ** add lineItem valid check here **
    return {
      name: o.name, 
      image: o.images[0], 
      price: lineItem.amount_total};
  });

var lineItems = [{amount_subtotal: 7500,amount_total: 700,description: 'The Spencer',},{amount_subtotal: 7500,amount_total: 500,description: 'The Gertie',}];
var arr = [{images: ['spencer image'],name: 'The Spencer',},{images: ['gertie image'],name: 'The Gertie'}];

// since your arrays are ordered the same you can access the second object using 
// the index passed from map.
const output = arr.map((o, i) => ({
  name: o.name, 
  image: o.images[0], 
  price: lineItems[i].amount_total}
));
console.log(output);

// if the two arrays are not in the same order you can use find() to retrieve 
// the second object by property (you'll need to check 
const outputUsingFind = arr.map(o => {
    const lineItem = lineItems.find(item => item.description === o.name);
    // ** add lineItem valid check here **
    return {
      name: o.name, 
      image: o.images[0], 
      price: lineItem.amount_total};
  });
console.log(outputUsingFind);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    猜你喜欢
    • 2013-03-07
    • 2012-02-26
    • 2012-06-29
    • 2011-10-05
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    相关资源
    最近更新 更多