【问题标题】:Javascript object to array, length = 0Javascript 对象到数组,长度 = 0
【发布时间】:2017-03-29 03:01:52
【问题描述】:

我正在建立一个网上商店,用户可以在其中为购物篮中的多个商店添加产品并结帐(例如 AliExpress)。

在购物车概览页面上,购物车的内容按商店排序显示。如果在不同的店铺多次添加相同的产品,则每个店铺都会展示该产品。

现在,我想为每个商店创建一个订单,其中包含该商店订购的产品。我正在使用 Angular 创建列表,其中包含按商店订购/过滤的产品。 该数据将被发送到我的 Node.JS 服务器,以循环内容并创建一些带有商品的订单。
我认为,问题在于数据是像“对象”而不是“数组”一样处理的。我找到了一个将对象转换为数组的函数,但长度仍为“0”。

如何处理数据以便循环浏览不同的项目?

AngularJS 代码按商店排序购物车

$scope.filterProducts = function(groupName) {
    $scope.productList = [];
    $http({
      method: 'GET',
      xhrFields: {withCredentials: true},
      url: '/loadCart'
    }).then(function successCallback(response){
        if (response.data) {
            var mapByShop = function(arr, groupName) {
                return arr.reduce(function(result, item) {
                    result[item[groupName]] = result[item[groupName]] || {};
                    result[item[groupName]][item['productId']] = item;
                    console.log('GROUPNAME en RESULT', groupName, result);
                    return result;
                }, {});
            };
            if (response.data.length > 0) {
                if (groupName == 'shopName') {
                    $scope.productList = mapByShop(response.data, groupName);
                } else {
                    $scope.checkoutList = mapByShop(response.data, groupName);
                }
            }
        }
    }, function errorCallback(response){
        console.log(response);
    });
  }

$scope.productList$http POST 函数中作为“数据”发送。

将对象转换为数组的Node.JS代码

function convertObjectToArray(object, cb){
    var cartContent = [];
    for (var i in object) {
        cartContent[i] = object[i];
    }
    console.log("convertObjectToArray");

    return cb(cartContent);
}

处理数据的代码(长度为零)

convertObjectToArray(req.body.cart, function(result){
    console.log(isArray(result));
    console.log('result', result);
    console.log("lenght", result.length);
})

仅供参考:isArray 函数

function isArray(myArray) {
    return myArray.constructor.toString().indexOf("Array") > -1;
}

【问题讨论】:

  • 仅供参考(这可能与问题有关,也可能无关),这是一个非常糟糕的isArray 功能。如果您在服务器端使用它,请更新到任何最新版本的 NodeJS 并改用 Array.isArray。如果没有,或者由于某种原因您无法升级,则您的 shim 代码应为 return Object.prototype.toString.call(myArray) === "[object Array]";
  • 可以使用angular.isArray判断是否为数组
  • 您可以将Array.isArray 用于isArray 功能
  • 啊,这个功能我只用于测试目的,我会删除它,当一切正常时。感谢您的提示!
  • 您希望结果集合(您称其为“数组”)的键是字符串还是整数?

标签: javascript angularjs arrays node.js object


【解决方案1】:

如果数组顺序不重要,你应该使用

cartContent.push(object[i]);

它会自动更新.length属性

【讨论】:

  • 没有顺序并不重要,因为商品是按商店排序的。非常简单,绝妙的解决方案。我要试试看!
【解决方案2】:

您的问题是您正在向数组对象添加属性,而不是使用数组 API 在对象中的整数位置插入。这意味着数组基本上保持“空”。如果您在插入数组时键入一个整数,那么您的代码会更好地工作。

破损的部分:

for (var i in object) {
    cartContent[i] = object[i];
}

i 在这里是一个字符串键,除非值强制为整数值(我认为),否则不会增加数组的长度。

这样的事情可能会奏效:

// Untested...
var keys = Object.keys(object);
for (var i = 0; i < keys.length; i++) {
    cartContent[i] = object[keys[i]];
}

或者像建议的其他答案一样,使用push API。

旁白:

如果您使用的是现代 JS 引擎,您可以:

  1. 使用Object.values,或

  2. 编写几个实用函数并使用以下方法将对象转换为数组

var o = iterable({foo:'fooValue', bar: 'barValue'});
console.log([...o]);

实用功能:

function iterable(o) {
    if(o[Symbol.iterator]) {
        return o;
    }

    o[Symbol.iterator] = iter.bind(null, o);
    return o;
}

function* iter(o) {
    var keys = Object.keys(o);
    for (var i=0; i<keys.length; i++) {
        yield o[keys[i]];
    }
}

【讨论】:

    猜你喜欢
    • 2017-11-10
    • 2021-10-02
    • 2022-01-14
    • 1970-01-01
    • 2011-08-01
    • 2018-07-16
    • 2010-09-05
    相关资源
    最近更新 更多